Codeup 并查集之问题 B: 畅通工程

分析

我们可以把有道路能达到的两个城市看作一个连通块,那么题中要求的就是连通块的数量。
假设有n个连通块,那么只需要在两个连通块间建一条路就可以满足要求,因此最后输出n-1就是要求的答案

转换到并查集中就是集合数-1

#include<iostream>
using namespace std;
int father[1010];
bool isroot[1010];
int cnt;
void init()
{
    
    
    for(int i=1;i<1010;i++)
    {
    
    
        father[i]=i;
        isroot[i]=false;
    }
    cnt=0;
}
int findfather(int a)
{
    
    
    int b=a;
    while(a!=father[a])//找根
    {
    
    
        a=father[a];
    }
    //路径压缩
    while(b!=father[b])
    {
    
    
        int c=b;
        b=father[b];
        father[c]=a;
    }
    return a;
}
void Union(int a,int b)//合并集合
{
    
    
    int faa=findfather(a);
    int fab=findfather(b);
    if(faa!=fab)
    {
    
    
        father[faa]=fab;
    }
}
int main()
{
    
    
    int n,m;
    while(cin>>n)
    {
    
    
        if(n==0)break;
        cin>>m;
        init();
        int a,b;
        for(int i=0;i<m;i++)
        {
    
    
            cin>>a>>b;
            Union(a,b);
        }
        for(int i=1;i<=n;i++)//将根置为true
        {
    
    
            isroot[findfather(i)]=true;
        }
        for(int i=1;i<=n;i++)
        {
    
    
            if(isroot[i])cnt++;
        }
        cout<<cnt-1<<endl;
    }
    return 0;
}