链接:https://www.nowcoder.com/acm/contest/139/D
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
题目描述
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.
题意很简单单,但是题目用各种专业的术语表达有点把人绕迷了。题意就是给定两个图 G1和G2 两个图的点个数V是相同的,问你G2的子图中有多少个与G1同构。
思路:因为题目的范围比较小,最多只有8个点,所以我们可以枚举所有的全排列,然后把G2中的点对应的替换一下,然后看看再G1中是否存在这条边如果,存在就用一个用一个变量++,如果最后存在的边数是与G1中边数相等,那么就是符合的。我们要把这个子图哈希成一个具体的值,因为同构图会有重复的,所以我们这里要哈希边,把边的序列哈希成一个值。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int MAX = 11;
int G[MAX][MAX];
class Edge{
public:
int u,v;
Edge();
Edge(int _u,int _v);
};
Edge edg[MAX*MAX];
typedef unsigned long long ull;
const ull B = 100000007;
int N,E1,E2;
int vec[MAX];
void init(){
memset(G,0,sizeof(G));
for(int i=1;i<=N;++i){
vec[i] = i;
}
}
int main(void){
while(cin >> N >> E1 >> E2){
init();
int u,v;
for(int i=1;i<=E1;++i){
cin >> u >> v;
G[u][v] = G[v][u] = 1;
}
for(int i=1;i<=E2;++i){
cin >> u >> v;
edg[i] = Edge(u,v);
}
set<ull> st;
do{
int cnt = 0;
ull temp = 0;
for(int i=1;i<=E2;++i){
int u = vec[edg[i].u],v = vec[edg[i].v];
//更换对应的点
if(G[u][v]){
cnt++;
//注意这里哈希的是边。每次选的边是一样的,就不会出现重复的
temp = temp*B + i;
}
}
if(cnt == E1){
st.insert(temp);
}
}while(next_permutation(vec+1,vec+1+N));
cout << (int)st.size() << endl;
}
return 0;
}
Edge::Edge(){
u = v = 0;
}
Edge::Edge(int _u,int _v){
u = _u;
v = _v;
}