D.Two Graphs 2018牛客多校第一场

链接: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;
 }

猜你喜欢

转载自blog.csdn.net/ii0789789789/article/details/81126774
今日推荐