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

2018牛客暑期ACM多校第一场D题
链接: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.
输入

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.

题目大意:求图G1有多少个子图和图G2是同构图
思路:枚举图G1的全排列子图,然后判断每一个子图是否和图G2是同构图

因为同构图不要求节点相同,只要求图的结构一样,所以要枚举每一个节点,比如说第二组样例,G1的节点分别是1 2 3,但是G2中子图有1 4 2(2 4 1)、 2 4 3(3 4 2)、3 4 1(1 4 3)三个子图跟G1同构。重复的情况就是类似于1 4 2和2 4 1这种情况。建议把图画出来。

AC代码:

#include<set>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 101;
const int mod = 1e9+7;

struct node
{
    int x,y;
} a[N];

int mp[N][N];

int main()
{
    int n,m1,m2,x,y;
    while(scanf("%d%d%d",&n,&m1,&m2)!=EOF)
    {
        memset(mp,0,sizeof(mp));

        for(int i=1; i<=m1; i++)
        {
            scanf("%d%d",&x,&y);
            mp[x][y]=mp[y][x]=1;    //无向图
        }

        for(int i=1; i<=m2; i++)
        {
            scanf("%d%d",&a[i].x,&a[i].y);
        }

        int vis[N];

        for(int i=1; i<=n; i++)
            vis[i]=i;               //用来枚举每一种情况

        set<int> s;     //用来去掉像第二组样例中1 4 2和2 4 1这种重复的清况

        do
        {
            int ha=0,num=0;
            for(int i=1; i<=m2; i++)//枚举G2中的每一条边
            {
                if(mp[vis[a[i].x]][vis[a[i].y]])
                {
                    ha=ha*199+i;//hash去重
                    ha%=mod;
                    num++;
                }
            }

            if(num==m1)
                s.insert(ha);
        }
        while(next_permutation(vis+1,vis+n+1));//全排列函数

        printf("%d\n",s.size());
    }
}

猜你喜欢

转载自blog.csdn.net/qq_42515626/article/details/81213359
今日推荐