ZOJ - 4109 - Welcome Party (并查集 + BFS + 优先队列)

Posted jiaaaake

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZOJ - 4109 - Welcome Party (并查集 + BFS + 优先队列)相关的知识,希望对你有一定的参考价值。

题目地址  

题目大意:n个人,m种关系 (a和b是朋友),可以看作 n个点,m条边, 用图论的知识解题

                  问在使最少人不开心的情况下,输出进房间字典序排序最小的顺序。(如果在小A进房间之前房间内没有他的朋友,他就不开心)

                  使用并查集分块,每个并查集的根节点和独立点(无朋友)的总个数就是输出的不开心的人数。

        使用BFS和优先队列遍历存入的图,保证字典序最小。将路径存入答案数组。

代码:

技术图片
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+5;

int s[maxn];
int vis[maxn];
vector<int> Edge[maxn];  //二维!
vector<int> sto;         //答案 

int Find(int t)

    return t==s[t]?t:s[t]=Find(s[t]);

void Merge(int st,int ed)

    int t1=Find(st);
    int t2=Find(ed);
    if(t1==t2) return;
    if(t1>t2)swap(t1,t2);
    s[t2]=t1;

void bfs(int root) 

    priority_queue<int,vector<int>,greater<int> > Q;  
    while(!Q.empty()) Q.pop();
    Q.push(root);
    vis[root] = 1;
    while(!Q.empty()) 
        int t = Q.top();
        Q.pop();
        sto.push_back(t);
    //    cout << " size = " << sto.size() << endl;
        for(int i = 0; i < Edge[t].size(); i++) 
            int temp = Edge[t][i];
            if(vis[temp]) continue;
            vis[temp] = 1;
            Q.push(temp);
        
    

int main()

    int T, n, m;
    cin >> T;
    while(T--) 
        int ans = 0;
        cin >> n >> m;
        sto.clear();      //清空答案数组!! 
        for(int i = 0; i <= n; i++)     //从0开始,把所有根节点和无朋友的点存在Edge[0]里面 
            s[i] = i;                    //并查集数组 
            Edge[i].clear();             //存边(两点 
            vis[i] = 0;                  //标记数组 
        
        for(int i = 1; i <= m; i++) 
            int x, y;
            cin >> x >> y;
            Edge[x].push_back(y);       //关系是相互的  所以在Merge时需要判断大小 
            Edge[y].push_back(x);
            Merge(x, y);
        
        for(int i = 1; i <= n; i++) 
            if(s[i] == i)              //所有的根节点 和 不存在边的点(无朋友的) 
                ans ++;
                Edge[0].push_back(i);
            
        
        bfs(0);
        printf("%d\n",ans);
        int len = sto.size();
        for(int i = 1; i < len-1; i++) 
            cout << sto[i] << " ";
        
        cout << sto[len-1] << endl;
    
    return 0;
View Code

 

以上是关于ZOJ - 4109 - Welcome Party (并查集 + BFS + 优先队列)的主要内容,如果未能解决你的问题,请参考以下文章

ZOJ - 4109 - Welcome Party (并查集 + BFS + 优先队列)

ZOJ4109 Welcome Party (并查集+优先队列)

P4109 [HEOI2015]定价

图论基础

无法编译生成的注册码 - MT4109

HDOJ4109拓扑OR差分约束求关键路径