链接:https://www.nowcoder.com/acm/contest/139/D
来源:牛客网
Two Graphs
时间限制: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.
题意:
给你一个小图,一个大图。
问你在大图中能找到多少个形状和小图一样的 在大图G2中找G1的同构子图
所以 把所有的G2所有的点存在一个a数组中,进行全排列 再进行点与点的一一映射
然后再与 G1 进行对应配对 看是否可满足同构
代码:
#include <iostream>
#include <string.h>
#include<algorithm>
#include <stdio.h>
#include <map>
using namespace std;
map<int,int>mp;
int n,m1,m2,x,y;
int mp1[10][10], mp2[10][10], a[10];
int main()
{
for(int i=1; i<=8; i++)
a[i] = i; // 初始化
while(scanf("%d%d%d",&n,&m1,&m2)!=EOF)
{
memset(mp1, 0, sizeof mp1); //存边
memset(mp2, 0, sizeof mp2); //记录边的编号以及是否有这条边
mp.clear();
for(int i=1; i<=m1; i++)
{
scanf("%d%d",&x,&y);
mp1[x][y] = mp1[y][x] = 1;//存在一条x到y的无向边
}
for(int i=1; i<=m2; i++)
{
scanf("%d%d",&x,&y);
mp2[x][y] = mp2[y][x] = i; // 第i条边编号为i
}
int ans = 0;
do
{
// G1 i -> G2 a[i] 映射关系
int flag = 1, b = 0;
// 判断是否满足映射关系
for(int i=1; i<=n; i++)//各各顶点
{
for(int j=1; j<=n; j++)
{
if(mp1[i][j]) // 当小图中有边则大图中必须有对应的边
{
if(mp2[a[i]][a[j]] == 0) flag = 0;
else b |= 1<<mp2[a[i]][a[j]];//状态压缩
}
}
}
if(flag && mp[b] == 0) // 如果满足并且这种状态没有出现过就答案+1
{
// for(int i=1;i<=n;i++)
// printf("%d\t",a[i]);
// puts("");
ans ++;
mp[b] = 1;//标记
}
}
while(next_permutation(a+1, a+1+n)); //全排列来得到所有可能的映射关系
printf("%d\n",ans);
}
return 0;
}