并查集 | 1107

很简单一个并查集的题,理解题意默写模板即可ac。

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>


#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 1010
#define MAX (1<<30)-1
#define V vector<int>

using namespace std;

int fa[LEN];

void init(){
    int i;
    F(i,1,LEN) fa[i]=i;
}

int findFa(int x){
    if(fa[x]==x) return x;
    int r=x;    //定义根
    while(fa[r]!=r) {
        r=fa[r];
    }
    //路径压缩
    int t=x;    //临时变量
    while(fa[t]!=t) {
        t=fa[t];    //往上层根节点走, 让循环得以完成 
        fa[x]=r;    //压缩路径 
        x=t;        //更新x 
    }
    return r; 
}

void Union(int a,int b){
    int fa_a=findFa(a);
    int fa_b=findFa(b);
    if(fa_a!=fa_b) fa[fa_a]=fa_b; 
}

int hobby[LEN];
int cnt[LEN];
int n,m; 

int main(){
//    freopen("1107.txt","r",stdin);
    I("%d",&n);
    init();
    int i,j,t;
    F(i,1,n+1){
        I("%d:",&m);
        FF(j,m){
            I("%d",&t);
            if(hobby[t]!=0) Union(i,hobby[t]);
            else hobby[t]=i;
        }
    }
    F(i,1,n+1) cnt[findFa(i)]++;
    vector<int> ans;
    F(i,1,n+1) if(cnt[i]) ans.push_back(cnt[i]);
    sort(ans.begin(),ans.end());
    reverse(ans.begin(),ans.end());
    O("%d
",ans.size());
    FF(i,ans.size()){
        O("%d",ans[i]) ;
        if(i!=ans.size()-1) O(" ");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/TQCAI/p/8534208.html