牛客网暑期ACM多校训练营(第一场)D.Two Graphs(图的同构)

链接: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条边的图E1,n个点,m2条边的图E2。求图E2有多少子图跟图E1同构。

题解:

  用STL的全排列函数next_permutation()枚举映射。对于每一种映射枚举每一条边判断合法性。

  总情况数要除以图E1的自同构数去重。

//Sinhaeng Hhjian
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int main(){
	int p[10], n, m1, m2, u, v, a[10][10], b[10][10];
	while(~scanf("%d%d%d", &n, &m1, &m2)){
		memset(a, 0, sizeof(a));
		memset(b, 0, sizeof(b));
		int ans=0, d=0;
		for(int i=1;i<=m1;i++){
			scanf("%d%d", &u, &v);
			a[u][v]=a[v][u]=1;
		}
		for(int i=1;i<=m2;i++){
			scanf("%d%d", &u, &v);
			b[u][v]=b[v][u]=1;
		}
		for(int i=1;i<=8;i++)
			p[i]=i;
		do{
			int flag=1;
			for(int i=1;i<=n && flag;i++)
				for(int j=1;j<=n && flag;j++)
					if(a[i][j] && !a[p[i]][p[j]])
						flag=0;
			if(flag)
				d++;
		}while(next_permutation(p+1, p+n+1));
		do{
			int flag=1;
			for(int i=1;i<=n && flag;i++)
				for(int j=1;j<=n && flag;j++)
					if(a[i][j] && !b[p[i]][p[j]])
						flag=0;
			if(flag)
				ans++;
		}while(next_permutation(p+1, p+n+1));
		printf("%d\n", ans/d);
	}
	return 0;
}

 

你可能感兴趣的:(******I,LOVE,GRAPH,THEORY*****)