题意:给出两个图G1和G2,问G2中找出与G1同构的子图有多少个。点数1<=n<=8。
思路:利用全排列做两个图的一一映射,然后判断G1的每条边是否的G2存在,最后将G2的满足满足同构的边做hash,记录刺痛狗情况记录。就是按照离散学的同构模拟一遍。
const int maxn=10;
int n,m1,m2,k,q,f;
int a[maxn][maxn],id[maxn],b[maxn];
int c[maxn][maxn];
int ct,cnt,tmp,flag,ans;
int vis[maxn];
map<int,int>mp;
int main()
{
int T,cas=1;
for(int i=1;i<=9;i++) b[i-1]=i;
while(scanf("%d %d %d",&n,&m1,&m2)!=EOF)
{
mp.clear();
memset(a,0,sizeof(a));
memset(c,0,sizeof(c));
f=1;
for(int i=0;i<m1;i++)
{
int x,y;
scanf("%d %d",&x,&y);
a[x][y]=a[y][x]=1;
}
for(int i=0;i<m2;i++)
{
int x,y;
scanf("%d %d",&x,&y);
c[x][y]=c[y][x]=f;
f<<=1;
}
ans=0;
int tmp=0;
while(1)
{
tmp=0;
int flag=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
if(a[i][j]&&!c[b[i-1]][b[j-1]])
{
flag=0;break;
}
if(a[i][j]&&c[b[i-1]][b[j-1]])
{
tmp|=c[b[i-1]][b[j-1]];
}
}
if(!flag) break;
}
if(!mp[tmp]) {ans+=flag;mp[tmp]=1;}
if(!next_permutation(b,b+n)) break;
}
printf("%d\n",ans);
}
return 0;
}