zoukankan      html  css  js  c++  java
  • 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,问G2的子图中有多少个与G1同构。

    题解:

    显然枚举子图不现实,假设phi(x)是从G1中的某个点映射到G2的某个点的函数,

    那么,从最开始 phi[1:n] = (1,2,3,…,n) 开始全排列,可以枚举出G1对应到G2的全部情况,只要判断G2中有没有相应的边即可。

    同时,要考虑自同构的情况,通过G1映射到自身判断是否自同构,最后答案除以自同构数即可。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=10;
    const int maxm=maxn*(maxn-1)/2;
    
    int n,m1,m2;
    int E1[maxn][maxn],u[maxm],v[maxm];
    int E2[maxn][maxn];
    int phi[maxn];
    
    int main()
    {
        while(scanf("%d%d%d",&n,&m1,&m2)!=EOF)
        {
            memset(E1,0,sizeof(E1));
            memset(E2,0,sizeof(E2));
            for(int i=1;i<=m1;i++) //G1
            {
                scanf("%d%d",&u[i],&v[i]);
                E1[u[i]][v[i]]=E1[v[i]][u[i]]=1;
            }
            for(int i=1,a,b;i<=m2;i++) //G2
            {
                scanf("%d%d",&a,&b);
                E2[a][b]=E2[b][a]=1;
            }
    
            for(int i=1;i<=n;i++) phi[i]=i; //初始化映射函数
            int ans=0,cnt=0;
            do
            {
                bool ok=1; //标记是否与G2的某个子图同构
                bool self=1; //标记是否自同构
                for(int i=1;i<=m1;i++)
                {
                    int a=phi[u[i]],b=phi[v[i]];
                    if(E2[a][b]==0) ok=0;
                    if(E1[a][b]==0) self=0;
                }
                if(ok) ans++;
                if(self) cnt++;
            }while(next_permutation(phi+1,phi+n+1));
    
            printf("%d
    ",ans/cnt);
        }
    }
  • 相关阅读:
    刚才遇到了关于C#使用外部DLL函数上的char*的问题。
    重新整理过的 《C#编码规范》
    晕,完全晕了。
    Microsoft Visual Studio 2010 支持html5和css3的补丁包
    [mysql] 修改root密码和查看连接数
    Visual Studio统计有效代码行数
    [c#] 邮件附件为中文名的bug
    游戏名词解释
    [SVN] 以下后缀文件不应该提交入库
    [c#] 语言新特性
  • 原文地址:https://www.cnblogs.com/dilthey/p/9346371.html
Copyright © 2011-2022 走看看