重新填坑——牛客暑期多校第一场D Two Graphs

关于图的同构,对于这道题而言,答案就是 G2子图中与G1同构的数目/G1自同构数,这样才不会重复计数。

求同构数目的过程与同构的定义有关,简单的说,如果对于点集的某一个排列,G1中有的边在G2中也有,那么说明G2的子图存在一个G1的同构。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define db double
#define m_p make_pair
#define p_b push_back
#define For(i,a,b) for(int i=a;i<=b;i++)
#define ls (root<<1)
#define rs ((root<<1)|1)
#define mst(a,b) memset(a,b,sizeof(a)) 
const int N=1e5+5;
const db eps=1e-8;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const int seed=131;
int n,m1,m2;
bool a[10][10],b[10][10];
int main(){
	ios::sync_with_stdio(false);
	while(cin>>n>>m1>>m2){
		mst(a,0);
		mst(b,0);
		int x,y;
		For(i,1,m1){
			cin>>x>>y;
			a[x][y]=a[y][x]=1;
		}
		For(i,1,m2){
			cin>>x>>y;
			b[x][y]=b[y][x]=1;
		}
		int p[10],s1=0,s2=0;
		For(i,1,n) p[i]=i;
		do{
			bool flag=0;
			For(i,1,n){
				For(j,1,n){
					if(i==j) continue;
					if(a[i][j]&&(!a[p[i]][p[j]])) flag=1;
					if(flag) break;
				}
				if(flag) break;
			}
			if(!flag) s1++;
		}while(next_permutation(p+1,p+1+n));
		do{
			bool flag=0;
			For(i,1,n){
				For(j,1,n){
					if(i==j) continue;
					if(a[i][j]&&(!b[p[i]][p[j]])) flag=1;
					if(flag) break;
				}
				if(flag) break;
			}
			if(!flag) s2++;
		}while(next_permutation(p+1,p+1+n));
		cout<<s2/s1<<"\n";
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38515845/article/details/89332093
今日推荐