给我一个基于c++的用于图的同构识别的代码,其中输入两个图的顶点和邻接矩阵输出是否同构,测试的有顶点数是否相同,顶点的度是否相同,度数相同的顶点数是否相同
时间: 2024-02-22 21:57:36 浏览: 66
以下是一个基于c++的用于图的同构识别的代码:
```c++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int MAXN = 100;
int n, m; // n: 顶点数,m: 边数
int a[MAXN][MAXN], b[MAXN][MAXN]; // 邻接矩阵
int pa[MAXN], pb[MAXN]; // pa[i], pb[i] 分别表示第一个图的第 i 个点的度数和第二个图的第 i 个点的度数
vector<int> da[MAXN], db[MAXN]; // da[i], db[i] 分别表示第一个图和第二个图中度数为 i 的点的集合
bool dfs(int cnt) {
if (cnt == n) return true; // 找到了一组同构
int x = -1, y = -1; // x 表示第一个图中的点,y 表示第二个图中的点
for (int i = 0; i < n; i++) {
if (pa[i] != pb[i]) return false; // 度数不同,不可能同构
if (da[pa[i]][pa[i] - 1] != db[pa[i]][pa[i] - 1]) return false; // 度数相同的点数不同,不可能同构
if (pa[i] == -1) continue;
if (x == -1 || da[pa[i]][x] < da[pa[i]][x]) x = i; // 找到第一个图中度数最小的点
}
for (int i = 0; i < n; i++) {
if (pb[i] == -1) continue;
if (y == -1 || db[pb[i]][y] < db[pb[i]][y]) y = i; // 找到第二个图中度数最小的点
}
for (int i = 0; i < pa[x]; i++) {
int u = a[x][i];
int v = -1;
for (int j = 0; j < pb[y]; j++)
if (b[y][j] == da[pa[u]][i]) {
v = j;
break;
}
if (v == -1) continue;
swap(pa[x], pa[u]);
swap(da[pa[x]][da[pa[x]].size() - 1], da[pa[x]][i]);
swap(pb[y], pb[v]);
swap(db[pb[y]][db[pb[y]].size() - 1], db[pb[y]][v]);
if (dfs(cnt + 1)) return true;
swap(pa[x], pa[u]);
swap(da[pa[x]][da[pa[x]].size() - 1], da[pa[x]][i]);
swap(pb[y], pb[v]);
swap(db[pb[y]][db[pb[y]].size() - 1], db[pb[y]][v]);
}
return false;
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
a[i][j] = b[i][j] = 0;
}
pa[i] = pb[i] = 0;
}
for (int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
a[u][pa[u]++] = v;
b[v][pb[v]++] = u;
}
for (int i = 0; i < n; i++) {
da[pa[i]].push_back(i);
db[pb[i]].push_back(i);
}
for (int i = 0; i <= n; i++) {
sort(da[i].begin(), da[i].end());
sort(db[i].begin(), db[i].end());
}
for (int i = 0; i < n; i++) {
if (pa[i] == 0) {
pa[i] = pb[i] = -1;
}
}
for (int i = 0; i <= n; i++) {
if (da[i].size() != db[i].size()) {
cout << "NO\n";
return 0;
}
}
if (dfs(0)) {
cout << "YES\n";
} else {
cout << "NO\n";
}
return 0;
}
```
这个代码的基本思路是:先判断两个图各个度数的点的个数是否相同,再从第一个图中找出度数最小的点,从第二个图中找出度数最小的点,然后依次尝试将第一个图中的度数最小的点和第二个图中的度数最小的点匹配,使用 DFS 搜索所有可能的匹配方案,直到找到一组同构或者所有方案都被尝试过。
阅读全文