题目
code
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include <math.h>
using namespace std;
int pre[1000],total;
/*int find_digui(int x){// 递归调用 但是容易造成栈溢出
if(pre[x]!=x)
pre[x]=find_digui(pre[x]);
return pre[x];
}*/
int find(int x){//循环路径压缩 找x的根节点
int p,temp;
p=x; //
while (pre[x]!=x) { //寻找根节点
x=pre[x];// x 2
}
while(p!=x){// p3 x2 x是p的上一级 p就是x。直到x的上一级就是x(找到根节点)
temp=pre[x]; //temp 2
pre[p]=x; //pre3 =2 把当前节点的父节点赋值为根节点
p=temp;// 3=2 更新节点
}
return x;
}
void join(int x,int y){
int p=find(x);
int q=find(y);
if(p!=q){// 根不一样时
pre[p]=q;//pre p的根节点就是q 那么p和q在一个集合
}
}
int main()
{
int m,n,start,end,total;
while(scanf("%d",&n)&&n){//m road
total=0;
scanf("%d",&m);
for(int i=1;i<=n;i++){// 初始化
pre[i]=i; // 自己是自己的掌门人!
}
while(m--){
scanf("%d%d",&start,&end);
join(start, end);// 合并
}
for(int i=1;i<=n;i++){// ⚠️ 不是0而是1~n
if(pre[i]==i){
total++;
}
}
printf("%d\n",total-1);
}
}
学到了
- 并查集
- 学习资料推荐
- https://www.bilibili.com/video/av8373130?from=search&seid=9058897506820070985
SWPU-ACM每周算法讲堂-并查集 一个b站上的up主讲课