题意:传送门
题解:
G
2
G_2
G2有多少个子图与
G
1
G_1
G1是同构关系,何为同构,题意说的很清了,也是自己离散数学上课没听过后悔脸,题目中的专业术语也是看了半天,说的是如果两个图,如果点相应对应的话,那么它两的邻接矩阵是一摸一样的,看下题目数据范围
1
≤
n
≤
8
1\le n \le 8
1≤n≤8,那么可以直接
n
!
n!
n!枚举
G
2
G_2
G2所有点,假设与
G
1
G_1
G1中的点相对应,然后判断邻接矩阵是否相同,最后还得处理一下
G
1
G_1
G1中的自同构数目,除以这个数目就是答案了。
附上代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=10;
int n,m1,m2,x,y,a[maxn],mp1[maxn][maxn],mp2[maxn][maxn];
int main()
{
while(scanf("%d%d%d",&n,&m1,&m2)==3){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
mp1[i][j]=0;mp2[i][j]=0;
}
}
for(int i=0;i<m1;i++){
scanf("%d%d",&x,&y);
mp1[x][y]=mp1[y][x]=1;
}
for(int i=0;i<m2;i++){
scanf("%d%d",&x,&y);
mp2[x][y]=mp2[y][x]=1;
}
for(int i=1;i<=n;i++){
a[i]=i;
}
int ans=0;
do{
int flag=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(mp1[i][j]==1&&mp2[a[i]][a[j]]==0){
flag=0;
break;
}
}
if(!flag){
break;
}
}
ans+=flag;
}while(next_permutation(a+1,a+n+1));
for(int i=1;i<=n;i++){
a[i]=i;
}
int tmp=0;
do{
int flag=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(mp1[i][j]==1&&mp1[a[i]][a[j]]==0){
flag=0;
break;
}
}
if(!flag){
break;
}
}
tmp+=flag;
}while(next_permutation(a+1,a+n+1));
printf("%d\n",ans/tmp);
}
return 0;
}