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} ∈ E 2.
Given two graphs and , count the number of graphs satisfying the following condition:
* .
* G 1 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;
}

  

猜你喜欢

转载自www.cnblogs.com/l609929321/p/9338520.html
今日推荐