2018牛客暑期ACM多校第一场D题
链接:https://www.nowcoder.com/acm/contest/139/D
来源:牛客网
题目描述
Two undirected simple graphs and where are isomorphic when there exists a bijection on V satisfying if and only if {x, y} ∈ E2.
Given two graphs and , count the number of graphs satisfying the following condition:
* .
* G1 and G are isomorphic.
输入描述:
The input consists of several test cases and is terminated by end-of-file.
The first line of each test case contains three integers n, m1 and m2 where |E1| = m1 and |E2| = m2.
The i-th of the following m1 lines contains 2 integers ai and bi which denote {ai, bi} ∈ E1.
The i-th of the last m2 lines contains 2 integers ai and bi which denote {ai, bi} ∈ E2.
输出描述:
For each test case, print an integer which denotes the result.
输入
3 1 2
1 3
1 2
2 3
4 2 3
1 2
1 3
4 1
4 2
4 3
输出
2
3
备注:
- 1 ≤ n ≤ 8
1 ≤ ai,bi ≤ n
- The number of test cases does not exceed 50.
题目大意:求图G1有多少个子图和图G2是同构图
思路:枚举图G1的全排列子图,然后判断每一个子图是否和图G2是同构图
因为同构图不要求节点相同,只要求图的结构一样,所以要枚举每一个节点,比如说第二组样例,G1的节点分别是1 2 3,但是G2中子图有1 4 2(2 4 1)、 2 4 3(3 4 2)、3 4 1(1 4 3)三个子图跟G1同构。重复的情况就是类似于1 4 2和2 4 1这种情况。建议把图画出来。
AC代码:
#include<set>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 101;
const int mod = 1e9+7;
struct node
{
int x,y;
} a[N];
int mp[N][N];
int main()
{
int n,m1,m2,x,y;
while(scanf("%d%d%d",&n,&m1,&m2)!=EOF)
{
memset(mp,0,sizeof(mp));
for(int i=1; i<=m1; i++)
{
scanf("%d%d",&x,&y);
mp[x][y]=mp[y][x]=1; //无向图
}
for(int i=1; i<=m2; i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
}
int vis[N];
for(int i=1; i<=n; i++)
vis[i]=i; //用来枚举每一种情况
set<int> s; //用来去掉像第二组样例中1 4 2和2 4 1这种重复的清况
do
{
int ha=0,num=0;
for(int i=1; i<=m2; i++)//枚举G2中的每一条边
{
if(mp[vis[a[i].x]][vis[a[i].y]])
{
ha=ha*199+i;//hash去重
ha%=mod;
num++;
}
}
if(num==m1)
s.insert(ha);
}
while(next_permutation(vis+1,vis+n+1));//全排列函数
printf("%d\n",s.size());
}
}