Is It A Tree?【北京大学复试上机题】【并查集】

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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值