牛客网暑期ACM多校训练营(第一场) Two Graphs

链接:https://www.nowcoder.com/acm/contest/139/D
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld

题目描述

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.

题意很简单,G为G1的同构,但是要去G2中寻找边来组成G。总结一下就是看G2有多少子图为G1

寻找同构思想很简单将点离散化1-n的排列组合 再去G2中寻找完全匹配

但是图的同构可以为 1 2 4 也可以为 2 1 4 所以会有重复出现 我们只需记录G1被重复了多少次再去重即可

#include <bits/stdc++.h>
using namespace std;
int zdy1[10][10];
int zdy2[10][10];
int mark1[100];
int mark2[100];
int T[20];
int main()
{
    int n,m1,m2,i,j;
    while(scanf("%d",&n)!=EOF)
    {
        memset(zdy1,0,sizeof(zdy1));
        memset(zdy2,0,sizeof(zdy2));
        scanf("%d%d",&m1,&m2);
        for(i=1;i<=m1;i++)
        {
            scanf("%d%d",&mark1[i],&mark2[i]);
            zdy1[mark1[i]][mark2[i]]=1;
            zdy1[mark2[i]][mark1[i]]=1;
        }
        for(i=1;i<=m2;i++)
        {
            int t1,t2;
            scanf("%d%d",&t1,&t2);
            zdy2[t1][t2]=1;
            zdy2[t2][t1]=1;
        }
        for(i=1;i<=n;i++)
            T[i]=i;
        int ans=0,k=0;
        do
        {
            int flag1=1,flag2=1;
            for(i=1;i<=m1;i++)
            {
                flag1&=zdy2[T[mark1[i]]][T[mark2[i]]];
                flag2&=zdy1[T[mark1[i]]][T[mark2[i]]];
            }
            if(flag1)
                ans++;
            if(flag2)
                k++;

        }while(next_permutation(T+1,T+n+1));
        printf("%d\n",ans/k);
    }
    return 0;
}
扫描二维码关注公众号,回复: 2443878 查看本文章

猜你喜欢

转载自blog.csdn.net/ljq199926/article/details/81213570
今日推荐