链接:http://acm.hdu.edu.cn/showproblem.php?pid=1272
题意:判断一个图是否不形成回路
条件:
① 根节点有且只有1个【保证能全通】
② 合并前根节点不同【如果根结点相同则二者相通,再合并就变成有多条相通的路径了】
#include<cstdio>
#include<cstring>
#define MAX 100001
#define Max(x,y) ((x)>(y)?(x):(y))
int f[MAX];
int vis[MAX];
int flag;
int find(int x) //非递归版路径压缩,防栈溢出
{
if( x == f[x] ) return x;
int rt=x;
while(rt!=f[rt]) //找到根结点
rt=f[rt];
int fx;
while(x!=rt) //压缩
{
fx=f[x];
f[x]=rt;
x=fx;
}
return x;
}
void merge(int x,int y)
{
x = find(x);
y = find(y);
if( x != y)
f[x]=y;
else
flag = 1; //如果两个点本来就相通,再合并就多通路
}
int main()
{
int i,a,b,tm,max;
int root;
// freopen("a.txt","r",stdin);
while( ~scanf("%d %d",&a,&b) )
{
flag = 0;
if( a == 0 && b == 0 ) //题目就是个坑
{
printf("Yes\n");
continue;
}
max = 1;
root = 0;
if ( a == -1 && b == -1 )
break;
for(i=1;i<=MAX;i++)
f[i] = i;
memset(vis,0,sizeof(vis));
vis[a] = vis[b] = 1; //牢记把前2个数也标记并合并
merge(a,b);
tm = Max(a,b);
max = Max(a,b);
while( ~scanf("%d %d",&a,&b),a+b )
{
merge(a,b);
tm = Max(a,b);
max = Max(tm,max);
vis[a] = vis[b] =1;
}
for(i=1;i<=max;i++)
{
if( flag == 1)
{
root = -1;
break;
}
if(f[i]==i && vis[i])
root++;
}
if(root == 1)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}