hdu 3926 Hand in Hand 判断两个度最多是2的无向图是否同构
2011-08-13 22:30
411 查看
[align=left]Problem Description[/align]
In order to get rid of Conan, Kaitou KID disguises himself as a teacher in the kindergarten. He knows kids love games and works out a new game called "hand in hand".
Initially kids run on the playground randomly. When Kid says "stop", kids catch others' hands immediately. One hand can catch any other hand randomly. It's weird to have more than two hands get together so one hand grabs at most one other hand. After kids stop
moving they form a graph.
Everybody takes a look at the graph and repeat the above steps again to form another graph. Now Kid has a question for his kids: "Are the two graph isomorphism?"
[align=left]Input[/align]
The first line contains a single positive integer T( T <= 100 ), indicating the number of datasets.
There are two graphs in each case, for each graph:
first line contains N( 1 <= N <= 10^4 ) and M indicating the number of kids and connections.
the next M lines each have two integers u and v indicating kid u and v are "hand in hand".
You can assume each kid only has two hands.
[align=left]Output[/align]
For each test case: output the case number as shown and "YES" if the two graph are isomorphism or "NO" otherwise.
[align=left]Sample Input[/align]
[align=left]Sample Output[/align]
//因为度最多是2,所以每一块是链或者是一个环。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100000;
struct edge
{
int v;
int next;
};
int V,E;
int p[maxn];
edge G[maxn];
int l;
void init()
{
l=0;
memset(p,-1,sizeof(p));
}
void addedge_double(int u,int v)
{
G[l].v=v;
G[l].next=p[u];
p[u]=l++;
G[l].v=u;
G[l].next=p[v];
p[v]=l++;
}
int a[maxn],b[maxn];
int la,lb;
void input()
{
init();
scanf("%d%d",&V,&E);
for(int i=0;i<E;i++)
{
int u,v;
scanf("%d%d",&u,&v);
addedge_double(u,v);
}
}
int vis[maxn];
int cnt;
int circle;
void dfs(int u,int fath)
{
vis[u]=1;cnt++;
for(int i=p[u];i!=-1;i=G[i].next)
{
int t=G[i].v;
if(t==fath) continue;
if(vis[t]) circle=1;
else dfs(t,u);
}
}
void solve(int a[maxn],int &l)
{
l=0;
memset(vis,0,sizeof(vis));
for(int i=1;i<=V;i++)
{
if(!vis[i])
{
cnt=0;
circle=0;
dfs(i,-1);
if(circle) cnt=-cnt;
a[l++]=cnt;
}
}
}
int same()
{
sort(a,a+la);
sort(b,b+lb);
if(la!=lb) return 0;
for(int i=0;i<la;i++) if(a[i]!=b[i]) return 0;
return 1;
}
int main()
{
int ci,pl=1;scanf("%d",&ci);
while(ci--)
{
input();
solve(a,la);
input();
solve(b,lb);
if(same()) printf("Case #%d: YES\n",pl++);
else printf("Case #%d: NO\n",pl++);
}
return 0;
}
In order to get rid of Conan, Kaitou KID disguises himself as a teacher in the kindergarten. He knows kids love games and works out a new game called "hand in hand".
Initially kids run on the playground randomly. When Kid says "stop", kids catch others' hands immediately. One hand can catch any other hand randomly. It's weird to have more than two hands get together so one hand grabs at most one other hand. After kids stop
moving they form a graph.
Everybody takes a look at the graph and repeat the above steps again to form another graph. Now Kid has a question for his kids: "Are the two graph isomorphism?"
[align=left]Input[/align]
The first line contains a single positive integer T( T <= 100 ), indicating the number of datasets.
There are two graphs in each case, for each graph:
first line contains N( 1 <= N <= 10^4 ) and M indicating the number of kids and connections.
the next M lines each have two integers u and v indicating kid u and v are "hand in hand".
You can assume each kid only has two hands.
[align=left]Output[/align]
For each test case: output the case number as shown and "YES" if the two graph are isomorphism or "NO" otherwise.
[align=left]Sample Input[/align]
2 3 2 1 2 2 3 3 2 3 2 2 1 3 3 1 2 2 3 3 1 3 1 1 2
[align=left]Sample Output[/align]
Case #1: YES Case #2: NO
//因为度最多是2,所以每一块是链或者是一个环。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100000;
struct edge
{
int v;
int next;
};
int V,E;
int p[maxn];
edge G[maxn];
int l;
void init()
{
l=0;
memset(p,-1,sizeof(p));
}
void addedge_double(int u,int v)
{
G[l].v=v;
G[l].next=p[u];
p[u]=l++;
G[l].v=u;
G[l].next=p[v];
p[v]=l++;
}
int a[maxn],b[maxn];
int la,lb;
void input()
{
init();
scanf("%d%d",&V,&E);
for(int i=0;i<E;i++)
{
int u,v;
scanf("%d%d",&u,&v);
addedge_double(u,v);
}
}
int vis[maxn];
int cnt;
int circle;
void dfs(int u,int fath)
{
vis[u]=1;cnt++;
for(int i=p[u];i!=-1;i=G[i].next)
{
int t=G[i].v;
if(t==fath) continue;
if(vis[t]) circle=1;
else dfs(t,u);
}
}
void solve(int a[maxn],int &l)
{
l=0;
memset(vis,0,sizeof(vis));
for(int i=1;i<=V;i++)
{
if(!vis[i])
{
cnt=0;
circle=0;
dfs(i,-1);
if(circle) cnt=-cnt;
a[l++]=cnt;
}
}
}
int same()
{
sort(a,a+la);
sort(b,b+lb);
if(la!=lb) return 0;
for(int i=0;i<la;i++) if(a[i]!=b[i]) return 0;
return 1;
}
int main()
{
int ci,pl=1;scanf("%d",&ci);
while(ci--)
{
input();
solve(a,la);
input();
solve(b,lb);
if(same()) printf("Case #%d: YES\n",pl++);
else printf("Case #%d: NO\n",pl++);
}
return 0;
}
相关文章推荐
- (hdu step 9.1.1)A == B ?(在这个数字有可能是大数并且存在无效0的情况下,判断这两个数字是否相等)
- hdu 1086 判断两个线段是否相交
- poj-1635 Subway tree systems(判断两个有根树是否同构)-哈希法
- 判断两个二叉树是否同构(相似)
- HDU 2826 || The troubles of lmy(判断两个N边形是否相似
- LeetCode-Isomorphic Strings:判断两个字符串是否同构(hashtable实现)
- HDU 3926 Hand in Hand(判断同构)
- java 程序题 判断两个字符串是否是同构的(isIsomorphic)
- 判断两个矩形是否相交
- hdu 3926 hand in hand(简化版图的同构)
- 输入两个正整数m和n(m<n),求m到n之间(包括m和n)所有素数的和,要求定义并调用函数isprime(x)来判断x是否为素数(素数是除1以外只能被自身整除的自然数)。
- 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一
- 一个算法:关于如何判断两个时间是否在允许误差内相等
- 编程之美3.6——编程判断两个链表是否相交
- java 判断两个二叉树是否完全相同
- 判断两个(float)变量x,z是否相等 以及和0值比较方法
- python判断两个文件是否相同
- 如何判断两个IP是否在同一网段
- 判断两个UIColor的颜色值是否相等
- 判断两个增序数组是否有重复(度娘)