链接: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.
示例1
输入
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.
思路:若想同构,就要找出一一对应的点来。对于E1中的所有的点和所有的边,一定要有E1中的点点所连的边在E2中都有。仔细看下面代码中最后的判断。这份代码可以说是十分暴力了。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,m1,m2,a,b;
int vis[10][10],pre[10],w[10],ans;
map<long long,int>mm;
struct AA
{
int x,y;
}pos[50];
int dfs(int rt)///枚举所有的点
{
if(rt==n+1)
{
long long pp=0;
for(int i=1;i<=m1;i++)
{
if(vis[pre[pos[i].x]][pre[pos[i].y]]==0)
return 0;
pp|=1<<vis[pre[pos[i].x]][pre[pos[i].y]];
}
if(mm[pp])
return 0;//判断选择的E2的边是否重复
ans++;
mm[pp]=1;
return 0;
}
for(int i=1;i<=n;i++)
{
if(w[i])
continue;
pre[rt]=i;//映射E1中的rt代表E2中的i
w[i]=1;
dfs(rt+1);
w[i]=0;
}
return 0;
}
int main()
{
while(~scanf("%d%d%d",&n,&m1,&m2))
{
mm.clear();
memset(vis,0,sizeof(vis));
memset(w,0,sizeof(w));
ans=0;
int x,y;
for(int i=1;i<=m1;i++)
{
scanf("%d%d",&x,&y);
pos[i].x=x;///E1中边的点
pos[i].y=y;
}
for(int i=1;i<=m2;i++)
{
scanf("%d%d",&x,&y);
vis[x][y]=vis[y][x]=i;///E2中的边的编号
}
dfs(1);
printf("%d\n",ans);
}
return 0;
}