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;
}

原文地址:https://www.cnblogs.com/JiaaaaKe/p/11294477.html

时间: 2024-08-02 21:49:35

ZOJ - 4109 - Welcome Party (并查集 + BFS + 优先队列)的相关文章

Welcome Party ZOJ - 4109 (思维+并查集)

题目链接: Welcome Party  ZOJ - 4109 题目大意:给你T组测试样例,然后n个人,m个关系,每一个关系包括两个人,这两个人为好朋友,然后问你怎么安排顺序,使得整个队伍的友情损失度最小(当一个人放置时,如果他的前面中没有他的朋友,那么整个队伍的朋友损失度就会加1) 具体思路:首先用并查集求出每一个联通块,然后用一个超级汇点连向这些连通块的根,然后优先队列+bfs求出字典序最小的正解就可以了. AC代码: 1 #include<bits/stdc++.h> 2 using n

ZOJ Problem Set - 3321 并查集

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3321 Circle Time Limit: 1 Second      Memory Limit: 32768 KB Your task is so easy. I will give you an undirected graph, and you just need to tell me whether the graph is just a circle.

ZOJ 3811 Untrusted Patrol 并查集+邻接表,注意所有点都要走过

Untrusted Patrol Time Limit: 3 Seconds      Memory Limit: 65536 KB Edward is a rich man. He owns a large factory for health drink production. As a matter of course, there is a large warehouse in the factory. To ensure the safety of drinks, Edward hir

ZOJ 3321 Circle【并查集】

解题思路:给定n个点,m条边,判断是否构成一个环 注意到构成一个环,所有点的度数为2,即一个点只有两条边与之相连,再有就是判断合并之后这n个点是否在同一个连通块 Circle Time Limit: 1 Second      Memory Limit: 32768 KB Your task is so easy. I will give you an undirected graph, and you just need to tell me whether the graph is just

并查集加优先队列

J - Welcome Party #include<bits/stdc++.h> using namespace std; const int maxn=1e6+10; int f[maxn]; int visf[maxn]; int vis[maxn]; int as[maxn]; vector<int> v[maxn]; priority_queue<int,vector<int>,greater<int> > q; int getf(in

并查集&amp;MST

[HDU] 1198 Farm Irrigation 基础最小生成树★ 1598 find the most comfortable road 枚举+最小生成树★★ 1811 Rank of Tetris 并查集+拓扑排序★★ 3926 Hand in Hand 同构图★ 3938 Portal 离线+并查集★★ 2489     Minimal Ratio Tree dfs枚举组合情况+最小生成树★ 4081     Qin Shi Huang's National Road System 最

ZOJ 3811 / 2014 牡丹江赛区网络赛 C. Untrusted Patrol bfs/dfs/并查集

Untrusted Patrol Time Limit: 3 Seconds                                     Memory Limit: 65536 KB Edward is a rich man. He owns a large factory for health drink production. As a matter of course, there is a large warehouse in the factory. To ensure t

ZOJ 3811 Untrusted Patrol bfs+并查集

题目链接:点击打开链接 题意: 给定n个点m条边的无向图,k个触发器. 下面k个数表示触发器安装在哪几个点. 下面m行给出边 最后有l个信号, 给出信号发出的触发器的顺序. 每个触发器只会发出一次信号,且一个点只有一个触发器. 有一个人在遍历图. 每经过一个点,那个点的触发器就会发出信号,问是否存在一种走法使得这个人遍历了所有点且触发器发出的信号顺序和给出的一样. 思路: 先把无触发器的点放到图里. 然后根据触发器的信号顺序把点依次加入图中,加入时只添加(与无触发器点相连的边) 然后判断这个点能

ZOJ 3811 Untrusted Patrol【并查集】

题目大意:给一个无向图,有些点有装监视器记录第一次到达该点的位置,问是否存在一条路径使得监视器以给定的顺序响起,并且经过所有点 思路:牡丹江网络赛的题,当时想了种并查集的做法,通神写完程序WA了几发,此时JYB用BFS秒了,索性最后还是调出来了,今天自己写了下,感觉唯一的坑点就是需要遍历完所有的点 //zoj3811 #include <stdio.h> #include <string.h> #include <algorithm> #include <queu