并查集入门

并查集思想是把相互之间有关系的事物捏成一块,即使形成通路,根据通路的数量得出所要结果,分成三部分来完成,一部分初始化,一部分查找祖宗节点,另一部分判断是否未同一祖宗,若是不作处理,否则将其中一个作为另一个的祖宗。查找祖宗时用路径压缩可以节省搜索时间
#include
#include
#include
using namespace std;
const int M_ax=1005;
int pre[M_ax],rk[M_ax];
void start(int n){
for(int i=1; i<=n; i++){
pre[i]=i; 初始化数组,是每个成员的祖宗都是自己
rk[i]=0; 树的深度,度数小的树并入大的可使度数不发生改变,后面判定使用
}
}
int find(int x){
if(xpre[x]) return x;查找祖宗节点,这里没有用到路径压缩,修改一下
else return find(pre[x]); return pre[x]=find(pre[x]);
}
void uni(int x,int y){
int fx=find(x);
int fy=find(y); 判定祖宗节点是否相同,不同的话开始并树,根据
if(fy
fx) return ; 树的深度来判断谁并谁
else {
if(rk[fx]<rk[fy]) pre[fx]=fy,rk[fx]=rk[fy];
else if(rk[fx]rk[fy]){
pre[fx]=fy;
rk[fy]++;
}
else pre[fy]=fx,rk[fy]=rk[fx];
}
}
int main()
{
int N,M;
while(cin>>N>>M,N){
int x,y;
start(N);
for(int i=0; i<M; i++){
cin>>x>>y;
uni(x,y);
}int sum=0;
for(int i=1; i<=N; i++)
{if(i
pre[i]) 祖宗节点是本身的即为一个通路
sum++;
}
cout<<sum-1<<endl;
}
return 0;
}
杭电1232畅通工程答案,求出通路数量然后减1即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值