题意:
给出若干对数字,前一个为后一个的父节点,结合所有给出的情况, 判断其是否组成一棵树。
思路:
显然这是一道求并查集的题,但和普通求并查集的题不同的是,这道题如果用数组,容易出问题,所以可以用map
感想:无
源代码:
#include<iostream>
#include<map>#include<cstring>
#include<stdio.h>
using namespace std;
map<int,int>M;
int set[100005]={0};
int root[100005]={0};
int vis[100005]={0};
int find(int x)
{
if(x==set[x]) return x;
return find(set[x]);
}
void merge(int a,int b)
{
set[find(b)]=find(a);
}
int main(void)
{
int a,b;
int n=1,k=1;
int flag=0;
while(scanf("%d%d",&a,&b)!=EOF)
{
if(a==-1 && b==-1) break;
if(a==0 && b==0){
int cnt=0;
for(int i=1;i<n;i++)
if(root[i]==0) cnt++; //条件1,只有一颗树
if(cnt>1) flag=1;
cnt=find(1);
for(int i=2;i<n;i++)
if(find(i)!=cnt) flag=1; //条件1
if(flag) printf("Case %d is not a tree.\n",k++);
else printf("Case %d is a tree.\n",k++);
n=1;flag=0;
M.clear();
memset(set,0,sizeof(set));
memset(vis,0,sizeof(vis));
memset(root,0,sizeof(root));
continue;
}
if(M[a]==0) M[a]=n++;
if(M[b]==0) M[b]=n++;
if(root[M[b]]!=0) flag=1; //条件2、3
root[M[b]]=M[a];
vis[M[a]]=vis[M[b]]=1;
merge(M[a],M[b]);
}
return 0;
}