poj 1308 并查集(判断一组点对是否能够组成树)

来源:互联网 发布:最喜欢的一句话知乎 编辑:程序博客网 时间:2024/06/08 14:44

题意:给定一组有序点对,如(a,b)表示有边从a指向b。问这组点对是否能够形成树。

思路:如果输入有(a,b),如果b没有其他前驱而且a不为b的前驱(或者a与b相等),则合并a和b,注意合并方向。对所有出现的点进行标记,最后通过father[i] = i的个数判断是树还是森林。

#include <stdio.h>#include <string.h>#define N 105int T=1,a,b;int father[N],num[N];void init(){int i;memset(num,0,sizeof(num));for(i = 1;i<N;i++)father[i] = i;}int find(x){if(father[x] == x)return x;return father[x] = find(father[x]);}void merge(int x,int y){father[y] = find(x);}int main(){freopen("a.txt","r",stdin);while(scanf("%d %d",&a,&b) && !(a==-1&&b==-1)){int flag = 1,i,j,sum;if(!a && !b){printf("Case %d is a tree.\n",T++);continue;}init();do{num[b] = num[a] = 1;if(find(a)!=find(b) && father[b] == b)merge(a,b);elseflag = 0;}while(scanf("%d %d",&a,&b) &&a&&b);if(flag)for(i = 1,sum=0;flag&&i<N;i++){if(num[i] && father[i]==i)sum++;if(sum > 1)flag=0;}if(!sum)flag = 0;if(flag)printf("Case %d is a tree.\n",T++);elseprintf("Case %d is not a tree.\n",T++);}return 0;}


0 0
原创粉丝点击