有G1,G2两个图G1边数较少
求G2中有几个子图与G1完全相同(点的编号只是相对的)
找出所有的对应关系,看G1是否完全被G2覆盖,并找出覆盖G1的那些边
因为点是相同的,所以如果边也是相同的,就说明这两个图是完全相同的
可以依据这点来去重
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <map>
using namespace std;
map<int,int>mp;
int n,m1,m2,x,y;
int mp1[10][10], mp2[10][10], a[10];
int main()
{
for(int i=1;i<=8;i++) a[i] = i; // 初始化
while(scanf("%d%d%d",&n,&m1,&m2)!=EOF){
memset(mp1, 0, sizeof mp1); // 存边
memset(mp2, 0, sizeof mp2); // 记录边的编号以及是否有这条边
mp.clear();
for(int i=1;i<=m1;i++){
scanf("%d%d",&x,&y);
mp1[x][y] = mp1[y][x] = 1;
}
for(int i=1;i<=m2;i++){
scanf("%d%d",&x,&y);
mp2[x][y] = mp2[y][x] = i; // 第i条边编号为i
}
int ans = 0;
do{
// G1 i -> G2 a[i] 映射关系
int flag = 1, b = 0;
// 判断是否满足映射关系
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(mp1[i][j]){ // 当小图中有边则大图中必须有对应的边
if(mp2[a[i]][a[j]] == 0) flag = 0;
else b |= 1<<mp2[a[i]][a[j]];
}
}
}
if(flag && mp[b] == 0){ // 如果满足并且这种状态没有出现过就答案+1
ans ++;
mp[b] = 1;
}
}while(next_permutation(a+1, a+1+n)); // 全排列来得到所有可能的映射关系
printf("%d\n",ans);
}
return 0;
}