ZOJ4109 Welcome Party

并查集算连通块的数量,集合的个数就是必然不开心的人数,再跑bfs,用优先队列维护~

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+14;
vector<int> g[maxn];
int father[maxn];
int N,M,T;
int isRoot[maxn];
int visit[maxn];
int findfather (int x) {
    int a=x;
    while (x!=father[x]) x=father[x];
    while (a!=father[a]) {
        int z=a;
        a=father[a];
        father[z]=x;
    }
    return x;
} 
void Union (int a,int b) {
    int faA=findfather (a);
    int faB=findfather (b);
    if (faA<faB) swap(faA,faB);
    father[faA]=faB;
}
int main () {
    scanf ("%d",&T);
    while (T--) {
        scanf ("%d %d",&N,&M);
        for (int i=1;i<=N;i++) father[i]=i,visit[i]=0,isRoot[i]=0;
        for (int i=1;i<=N;i++) g[i].clear();
        int x,y;
        for (int i=0;i<M;i++) {
            scanf ("%d %d",&x,&y);
            g[x].push_back(y);
            g[y].push_back(x);
            Union (x,y);
        }
        for (int i=1;i<=N;i++) isRoot[findfather(i)]++;
        int ans=0;
        priority_queue<int,vector<int>,greater<int>> q;
        for (int i=1;i<=N;i++) {
            if (isRoot[i]) {
                ans++;
                visit[i]=1;
                q.push(i);
            }
        }
        printf ("%d\n",ans);
        while (!q.empty()) {
            int u=q.top();
            q.pop();
            printf ("%d",u);
            for (int i=0;i<g[u].size();i++) 
            if (!visit[g[u][i]]) q.push(g[u][i]),visit[g[u][i]]=1;
            if (!q.empty()) printf (" ");
        }
        printf ("\n");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/zhanglichen/p/12304583.html
今日推荐