zoukankan      html  css  js  c++  java
  • Two Graphs 牛客网暑期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, m

    1

     and m

    2

     where |E

    1

    | = m

    1

     and |E

    2

    | = m

    2

    .
    The i-th of the following m

    1

     lines contains 2 integers a

    i

     and b

    i

     which denote {a

    i

    , b

    i

    } ∈ E

    1

    .
    The i-th of the last m

    2

     lines contains 2 integers a

    i

     and b

    i

     which denote {a

    i

    , b

    i

    } ∈ E

    2

    .

    输出描述:

    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 ≤ a

    i

    , b

    i

     ≤ n
    * The number of test cases does not exceed 50.


    求图G1有多少个子图和图G2是同构图
    枚举图G1的全排列子图,然后判断每一个子图是否和图G2是同构图
    判断原理:
    同构要求边,点以及点的结构都相同。
    我们先存好图G1中每种边点结构的关系,用一个vis数组存下每条边
    然后在全排列判断每个子图的时候判断这个子图是否和图G2同构,同构就用个set保存下这种情况(每种情况用散列哈希求出一个独一无二的值)
    最后set的size就是结果
    #include <map>
    #include <set>
    #include <stack>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <vector>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define debug(a) cout << #a << " " << a << endl
    using namespace std;
    const int maxn = 1e1;
    const int mod = 1e9 + 7;
    typedef long long ll;
    ll vis[maxn][maxn], f[maxn];
    pair<ll,ll> p[maxn*10];
    int main() {
        ll n, m1, m2;
        while( cin >> n >> m1 >> m2 ) {
            memset( vis, 0, sizeof(vis) );
            for( ll i = 1; i <= n; i ++ ) {
                f[i] = i;
            }
            for( ll i = 1, a, b; i <= m1; i ++ ) {
                cin >> a >> b;
                vis[a][b] = vis[b][a] = 1;
            }
            for( ll i = 1; i <= m2; i ++ ) {
                cin >> p[i].first >> p[i].second;
            }
            set<ll> s;
            do{
                ll ha = 0, cnt = 0;
                for( ll i = 1; i <= m2; i ++ ) {
                    if( vis[f[p[i].first]][f[p[i].second]] ) {  //判断边点结构
                        ha = ha*133 + i; //散列求点,确保每种情况得到的点不一样
                        ha %= mod;
                        cnt ++;   //判断边
                    }
                }
                if( cnt == m1 ) {
                    s.insert(ha);
                }
            } while( next_permutation(f+1,f+n+1) ); //全排列图G1
            cout << s.size() << endl;
        }
        return 0;
    }
    

      

    彼时当年少,莫负好时光。
  • 相关阅读:
    [YTU]_2417 C语言习题 字符串长度
    最小生成树学习笔记
    后缀数组学习笔记
    网络流的几个小优化
    面向对象
    Manacher(马拉车)学习笔记
    EXKMP学习笔记QAQ
    GDOI DAY1游记
    GDOI--DAY2 游记
    caioj:1348: [NOIP普及组2012]质因数分解 C++
  • 原文地址:https://www.cnblogs.com/l609929321/p/9338520.html
Copyright © 2011-2022 走看看