题目说的很清楚,判断同构图。
知道了同构图的定义后就不难判断了。
同构图:
图论当中的术语,假设G=(V,E)和G1=(V1,E1)是两个图,如果存在一个双射m:V→V1,使得对所有的x,y∈V均有xy∈E等价于m(x)m(y)∈E1,则称G和G1是同构的,这样的一个映射m称之为一个同构。
简单的说,就是两个图 环数相同,链数相同,这些环,链在两个图中要大小对应相等。
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
const int MAXN = 1e4 + 10;
const int NIL = -1;
int parent[MAXN];
enum STATUS { list, circle };
struct Node {
STATUS status;
int size;
bool operator< (const Node& n) const
{
if (size == n.size)
return status < n.status;
return size < n.size;
}
} v[2][MAXN];
int N[2];
int find_parent(int x)
{
if (parent[x] == NIL)
return x;
return parent[x] = find_parent(parent[x]);
}
void init(int id, int n)
{
for (int i = 0; i <= n; ++i)
{
parent[i] = NIL;
}
for (int i = 0; i <= n; ++i)
v[id][i].size = 1, v[id][i].status = list;
}
void solve(int id)
{
int n, m, a, b;
scanf("%d %d", &n, &m);
N[id] = n;
init(id, n);
for (int i = 0; i < m; ++i)
{
scanf("%d %d", &a, &b);
int pa = find_parent(a);
int pb = find_parent(b);
if (pa != pb)
{
parent[pb] = pa;
v[id][pa].size += v[id][pb].size;
v[id][pb].size = 0;
}
else
v[id][pa].status = circle;
}
sort(v[id] + 1, v[id] + n + 1);
}
bool ok()
{
if (N[0] != N[1])
return false;
for (int i = 1; i <= N[0]; ++i)
if (v[0][i].size != v[1][i].size || v[0][i].status != v[1][i].status)
return false;
return true;
}
int main(void)
{
int T, n, m;
scanf("%d", &T);
for (int t = 1; t <= T; ++t)
{
solve(0);
solve(1);
printf("Case #%d: ", t);
if (ok())
puts("YES");
else
puts("NO");
}
}