题意:给定一组有序点对,如(a,b)表示有边从a指向b。问这组点对是否能够形成树。
思路:如果输入有(a,b),如果b没有其他前驱而且a不为b的前驱(或者a与b相等),则合并a和b,注意合并方向。对所有出现的点进行标记,最后通过father[i] = i的个数判断是树还是森林。
#include <stdio.h>
#include <string.h>
#define N 105
int 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);
else
flag = 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++);
else
printf("Case %d is not a tree.\n",T++);
}
return 0;
}
本文介绍了一种算法,用于判断给定的一组有序点对是否能构成一棵树。通过并查集实现节点间的合并,并利用标记记录节点状态,最终统计独立节点数量来判断结构是否为树。
1万+

被折叠的 条评论
为什么被折叠?



