给定两个无向图 $G_1,G_2$,判断它们是否同构。图的同构是指两个图的节点可以通过某种重新编号的方式完全匹配,且边的连接关系一致。为了简化问题,假设图的节点编号从 $0$ 到 $n-1$,并且图的边以邻接表的形式给出。下面程序中横线处应该给出的是( )。
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
string graphHash(vector<vector<int>>& graph) {
vector<string> nodeHashes(graph.size());
for (int i = 0; i < graph.size(); i++) {
vector<int> neighbors = graph[i];
sort(neighbors.begin(), neighbors.end());
string hash;
for (int neighbor : neighbors) {
// 在此处填入代码
}
nodeHashes[i] = hash;
}
sort(nodeHashes.begin(), nodeHashes.end());
string finalHash;
for (string h : nodeHashes) {
finalHash += h + "*";
}
return finalHash;
}
int main() {
int n;
cin >> n;
vector<vector<int>> G1(n);
for (int i = 0; i < n; i++) {
while (cin >> k) {
G1[i].push_back(k);
if (cin.get() == '\n') break;
}
}
vector<vector<int>> G2(n);
for (int i = 0; i < n; i++) {
while (cin >> k) {
G2[i].push_back(k);
if (cin.get() == '\n') break;
}
}
string hash1 = graphHash(G1);
string hash2 = graphHash(G2);
if (hash1 == hash2) {
cout << "YES" << endl;
} else {
cout << "NO" << endl;
}
return 0;
}根据上下文和C++语法规则确定空缺处应填的内容,关注函数调用参数、表达式和返回值类型。
填空时注意语法完整性:分号、括号匹配、函数参数类型和个数、返回值类型。
【考点】字符串处理|排序|哈希
🎯 考纲定位 本题考查 GESP 七级《C++ 程序设计》中「字符串与哈希」模块。命题人刻意避开复杂图论,用哈希思想压缩同构判断——这是绝大多数考生会直接想模拟重编号/回溯的硬伤区,七级图论题改成哈希题就是卡住这个思维定式。
🧠 解题思维 哈希函数本质是「把无序对象映射成唯一字符串」。对每个节点,先把邻接表排序(去重编号),然后逐个邻居转成字符串拼接——这样节点 i 的 hash 里就隐式包含了「和哪些点相连」的信息。最后把所有节点的 hash 再排序拼接,就消去了节点顺序的影响,得到图的全局指纹。
🪤 陷阱拆解
hash -= 字符串是非法操作,编译器直接报错。to_string(neighbor) 后加逗号作为分隔符,才是构造唯一字符串的正确方式。这道题最阴险的就是「看起来像 A 就能跑」——其实不加分隔符,哈希碰撞概率极高。🔄 反命题思维 如果图是有向的,只需把邻接表改作「出边」排序即可;如果要求方案数而非是否同构,哈希就得改成计数或保留多重边。刷到「图同构/异构」类题,先问自己:命题人是要我模拟重编号,还是用哈希压缩?