您的位置:首页 > 其它

hdu 1272 判断所给的图是不是生成树 (并查集)

2015-06-23 12:43 459 查看

判断所给的图是不是生成树,如果有环就不是,如果没环但连通分量大于1也不是

find函数 用递归写的话 会无限栈溢出 Orz
要加上那一串 手动扩栈

Sample Input
6 8 5 3 5 2 6 4
5 6 0 0

8 1 7 3 6 2 8 9 7 5
7 4 7 8 7 6 0 0

3 8 6 8 6 4
5 3 5 6 5 2 0 0

-1 -1

Sample Output
Yes
Yes
No

 

# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <cmath>
# include <queue>
# define LL long long
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std ;

const int MAXN=100010;
int F[MAXN];
bool vis[MAXN] ;
int save[MAXN] ;
bool flag ;
int find(int x)//找x的祖先结点
{
if(F[x]==x) return x;
return F[x]=find(F[x]);
}
void bing(int u,int v)
{
int t1=find(u);
int t2=find(v);
if(t1!=t2) F[t1]=t2;
else flag = 1 ; //有环
}
int main()
{
//freopen("in.txt","r",stdin) ;
int u , v ;
while(scanf("%d %d" , &u , &v) != EOF)
{
if (u == -1 && v == -1)
break ;
if (u == 0 && v == 0)
{
printf("Yes\n") ;
continue ;
}
int i ;
for(i=1;i<MAXN;i++)
{
F[i]=i;
}
memset(vis , 0 , sizeof(vis)) ;
F[u] = v ;
int l = 0 ;
flag = 0 ;
if (!vis[u])
{
vis[u] = 1 ;
save[l++] = u ;
}
if (!vis[v])
{
vis[v] = 1 ;
save[l++] = v ;
}
while(scanf("%d %d" , &u , &v))
{
if (u == 0 && v == 0)
break ;
if (flag)
continue ;
if (!vis[u])
{
vis[u] = 1 ;
save[l++] = u ;
}
if (!vis[v])
{
vis[v] = 1 ;
save[l++] = v ;
}
bing(u,v) ;
}
int res = 0 ; //连通分量
for (i = 0 ; i < l ; i++)
if (F[save[i]] == save[i])
res++ ;
if (res >= 2 || flag == 1)
printf("No\n") ;
else
printf("Yes\n") ;
}
return 0;
}
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: