链接: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.
题意
两个图都有N个点,第一个图有M1条边,第二个图有M2条边,问第二个图中有多少个子图跟第一个图同构
思路
用STL的全排列函数next_permutation()枚举映射。对于每一种映射枚举每一条边判断合法性。总情况数要除以图E1的自同构数去重。
#include<bits/stdc++.h>
using namespace std;
int a[10][10];
int b[10][10];
int p[10];
int main()
{
int n,m1,m2;
int u,v,ans1,ans2;
while(~scanf("%d %d %d",&n,&m1,&m2) )
{
ans1 = ans2 = 0;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i = 0;i < m1;i ++)
{
scanf("%d %d",&u,&v);
a[u][v] = a[v][u] = 1;
}
for(int i = 0;i < m2;i ++)
{
scanf("%d %d",&u,&v);
b[u][v] = b[v][u] = 1;
}
for(int i = 1;i <= n;i ++)
p[i] = i;
do
{
int f = 1;
for(int i = 1;i <= n;i ++)
{
for(int j = 1;j <= n;j ++)
{
if(a[i][j] && !(a[p[i]][p[j]]))
f = 0;
}
}
if(f)
ans1 ++;
}while(next_permutation(p+1,p + 1+ n));///判断图一中 自身的同构数
do
{
int f = 1;
for(int i = 1;i <= n;i ++)
{
for(int j = 1;j <= n;j ++)
{
if(a[i][j] && !(b[p[i]][p[j]]))
f = 0;
}
}
if(f)
ans2 ++;
}while(next_permutation(p+1,p + 1+ n)); ///判断图二中 跟图一同构的子图数量
printf("%d\n",ans2/ans1);
}
return 0;
}