考研机试 这是一棵树吗

这篇文章详细介绍了如何使用并查集数据结构来判断一组边是否能形成一棵树,包括初始化、查找和合并操作,以及对入度和连通性的检查。
摘要由CSDN通过智能技术生成

这是一棵树吗

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
树非空 根节点入度为0
其他入度为1
最后的树不能成环
1.入度 不存在入度大于2的节点
2.已连通的 加入一个新边
3.边数=顶点数-1

#include <iostream>
#include <vector>
using namespace std;
int father[10001];
void InitDisjointSet(int n){
    for(int i=0;i<n;++i){
        father[i]=i;
    }
}
int FindDisjointSet(int u){
    if(father[u]==u){
        return u;
    }else{
        father[u]= FindDisjointSet(father[u]);
        return father[u];
    }
}
void UnionDisjointSet(int u,int v){
    int uroot= FindDisjointSet(u);
    int vroot=FindDisjointSet(v);
    father[vroot]=uroot;
}
int main(){
 int u,v;
 InitDisjointSet(10001);
 int  edgeCount=0;
 int  vertexCount=0;
 vector<int> vertex(10001);
 vector<int> inDegree(10001);
 bool isOK=true;
 int caseIndex=1;
 while(1){
     scanf("%d%d",&u,&v);
     if(u==-1&&v==-1){
         break;
     }else if(u==0&&v==0){
         if(vertexCount!=edgeCount+1){
             isOK=false;
         }
         if(vertexCount==0&&edgeCount==0){
             isOK=true;
         }
         if(isOK== true){
             printf("Case %d is a tree.\n",caseIndex);
         }else{
             printf("Case %d is not a tree.\n",caseIndex);
         }
         //重置
         InitDisjointSet(10001);
         edgeCount=0;vertexCount=0;
         for(int i=0;i<10001;++i){
             vertex[i]=0;
             inDegree[i]=0;
         }
         isOK=true;
         ++caseIndex;
         //一个图的所有边已经记录完成了
     }else{
         //往当前图加入新边
         ++edgeCount;
         if(vertex[u]==0){
             vertex[u]=1;
             ++vertexCount;
         }
         if(vertex[v]==0){
             vertex[v]=1;
             ++vertexCount;
         }
         //判断uv是否连通
         if(FindDisjointSet(u)== FindDisjointSet(v)){
             isOK=false;
         }else{
             UnionDisjointSet(u,v);
         }
         ++inDegree[v];
         if(inDegree[v]>=2){
             isOK=false;
         }
     }
 }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值