并查集思想是把相互之间有关系的事物捏成一块,即使形成通路,根据通路的数量得出所要结果,分成三部分来完成,一部分初始化,一部分查找祖宗节点,另一部分判断是否未同一祖宗,若是不作处理,否则将其中一个作为另一个的祖宗。查找祖宗时用路径压缩可以节省搜索时间
#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(fyfx) 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(ipre[i]) 祖宗节点是本身的即为一个通路
sum++;
}
cout<<sum-1<<endl;
}
return 0;
}
杭电1232畅通工程答案,求出通路数量然后减1即可
并查集入门
最新推荐文章于 2023-04-03 23:34:50 发布