Every node except the root has exactly one edge pointing to it.There is a unique sequence of directed edges from the root to each node.
除了根节点外的其他节点都有正好一条边指向他,从根节点到每一个点都有一个独一无二的有向边序列
所以这个题需要考虑3点,
- 一是连通图只有一个
- 二是根节点只有一个(即入度为0的节点。这里主要是考虑到了有向图)
- 三是每个节点的入度最多只有一个
并查集的初始化查找合并照常
#include<iostream>
using namespace std;
int MAXN=10005;
int father[10005];
int height[10005];
int inDegree[10005];
int visited[10005];
void Init(){
for(int i=0;i<MAXN;i++){
father[i]=i;
height[i]=0;
inDegree[i]=0;
visited[i]=0;
}
}
int Find(int x){
if(x!=father[x]){
father[x]=Find(father[x]);
}
return father[x];
}
void Union(int x,int y){
x=Find(x);
y=Find(y);
if(x!=y){
if(height[x]>height[y]){
father[x]=y;
}
else if(height[x]<height[y]){
father[y]=x;
}
else{
father[y]=x;
height[x]++;
}
}
}
bool istree(){
int count=0; //连通图的个数
int root=0;
bool flag=true;
for(int i=0;i<MAXN;i++){
if(visited[i]){
if(Find(i)==i){ //连通图
count++;
}
if(inDegree[i]==0){ //根节点
root++;
}
if(inDegree[i]>1){ //入度不为1
flag=false;
}
}
}
if(count!=1 || root!=1){
flag=false;
}
if(count==0 && root==0){
flag=true;
}
return flag;
}
int main(){
int x,y;
int casenumber=0;
Init();
while(scanf("%d%d",&x,&y)!=EOF){
if(x==-1&&y==-1){
break;
}
if(x==0 && y==0){
casenumber++;
if(istree()){
printf("Case %d is a tree.\n",casenumber);
}
else{
printf("Case %d is not a tree.\n",casenumber);
}
Init();
}
else{
//不是0 0
Union(x,y);
visited[x]=1;
visited[y]=1;
inDegree[y]++;
}
}
return 0;
}