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

题目链接:

Welcome Party

 ZOJ - 4109

题目大意:给你T组测试样例,然后n个人,m个关系,每一个关系包括两个人,这两个人为好朋友,然后问你怎么安排顺序,使得整个队伍的友情损失度最小(当一个人放置时,如果他的前面中没有他的朋友,那么整个队伍的朋友损失度就会加1)

具体思路:首先用并查集求出每一个联通块,然后用一个超级汇点连向这些连通块的根,然后优先队列+bfs求出字典序最小的正解就可以了。

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 # define inf 0x3f3f3f3f
 4 # define ll long long
 5 const int maxn = 2e6+100;
 6 int father[maxn];
 7 vector<int>Edge[maxn];
 8 vector<int>sto;
 9 int vis[maxn];
10 int Find(int t)
11 {
12     return t==father[t]?t:father[t]=Find(father[t]);
13 }
14 void mege(int st,int ed)
15 {
16     int t1=Find(st);
17     int t2=Find(ed);
18     if(t1==t2)return ;
19     if(t1>t2)swap(t1,t2);
20     father[t2]=t1;
21 }
22 void bfs(int root)
23 {
24     priority_queue<int,vector<int>,greater<int> >q;
25     while(!q.empty())q.pop();
26     q.push(root);
27     vis[root]=1;
28     while(!q.empty())
29     {
30         int top=q.top();
31         q.pop();
32     //    if(top!=0)
33         sto.push_back(top);
34         for(int i=0; i<Edge[top].size(); i++)
35         {
36             int to=Edge[top][i];
37             if(vis[to])
38                 continue;
39             vis[to]=1;
40             q.push(to);
41         }
42     }
43 }
44 int main()
45 {
46     int T;
47     scanf("%d",&T);
48     while(T--)
49     {
50         int n,m,st,ed;
51         scanf("%d %d",&n,&m);
52         sto.clear();
53         for(int i=0; i<=n; i++)//注意从0开始清空
54         {
55             father[i]=i;
56             Edge[i].clear();
57             vis[i]=0;
58         }
59         for(int i=1; i<=m; i++)
60         {
61             scanf("%d %d",&st,&ed);
62             Edge[st].push_back(ed);
63             Edge[ed].push_back(st);
64             mege(st,ed);
65         }
66         int ans=0;
67         for(int i=1; i<=n; i++)
68         {
69             if(Find(i)!=i)
70                 continue;
71             Edge[0].push_back(i);
72             ans++;
73         }
74         bfs(0);
75         printf("%d\n",ans);
76         for(int i=1; i<sto.size(); i++)
77         {
78             if(i==1)
79                 printf("%d",sto[i]);
80             else
81                 printf(" %d",sto[i]);
82         }
83         printf("\n");
84     }
85     return 0;
86 }

 

原文地址:https://www.cnblogs.com/letlifestop/p/10804321.html

时间: 2024-08-07 10:05:09

Welcome Party ZOJ - 4109 (思维+并查集)的相关文章

Codeforces Round #423 (Div. 2) C 思维,并查集 或 线段树 D 树构造,水

Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) C. String Reconstruction   思维,并查集 或 线段树 题意:一个字符串被删除了,但给出 n条信息,要还原出可能的字典序最小的字符串.信息有:字符串ti,ki个位置xi,表明原本的字符串在xi位置是以字符串ti开头的. tags:惨遭 fst,一开始把所有字符串都存下来,排序做的,结果爆内存了.. 方法1: 考虑并查集,对于字符串 ti,在位置xi,

ZOJ 2833-Friendship(并查集+优化)

Friendship Time Limit: 3 Seconds      Memory Limit: 32768 KB A friend is like a flower, a rose to be exact, Or maybe like a brand new gate that never comes unlatched. A friend is like an owl, both beautiful and wise. Or perhaps a friend is like a gho

ZOJ 3321 Circle(并查集啊)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3731 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. A cycle is three or more nodes V1, V2, V3, ...Vk, such th

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

题目地址 题目大意:n个人,m种关系 (a和b是朋友),可以看作 n个点,m条边, 用图论的知识解题 问在使最少人不开心的情况下,输出进房间字典序排序最小的顺序.(如果在小A进房间之前房间内没有他的朋友,他就不开心) 使用并查集分块,每个并查集的根节点和独立点(无朋友)的总个数就是输出的不开心的人数.     使用BFS和优先队列遍历存入的图,保证字典序最小.将路径存入答案数组. 代码: #include <bits/stdc++.h> using namespace std; const i

HDU 4496 D-City(并查集,逆思维)

题目 熟能生巧...常做这类题,就不会忘记他的思路了... //可以反过来用并查集,还是逐个加边,但是反过来输出...我是白痴.....又没想到 //G++能过,C++却wa,这个也好奇怪呀... #include<stdio.h> #include<string.h> int fx,fy,r,bin[10010]; int x[100010],y[100010],n,m,i,count,ans[100010],j; int find(int x) { //改成这样就不会超时了么好

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 3659 Conquer a New Region 并查集+贪心

点击打开链接题目链接 Conquer a New Region Time Limit: 5 Seconds      Memory Limit: 32768 KB The wheel of the history rolling forward, our king conquered a new region in a distant continent. There are N towns (numbered from 1 to N) in this region connected by s

hdu6074[并查集+LCA+思维] 2017多校4

看了标答感觉思路清晰了许多,用并查集来维护全联通块的点数和边权和. 用另一个up[]数组(也是并查集)来保证每条边不会被重复附权值,这样我们只要将询问按权值从小到大排序,一定能的到最小的边权和与联通块中的点数. 下面是过程分析.过程中一共运用了两个并查集. [数据]110 31 21 32 42 53 63 74 85 95 109 6 3 1 501 4 2 5 209 10 8 10 40[分析]首先我们将图构建出来我们将m次询问按权值从小到大排序后: 1 4 2 5 209 10 8 10

HDU 1116 || POJ 1386 || ZOJ 2016 Play on Words (欧拉回路+并查集)

题目链接 题意 : 有很多门,每个门上有很多磁盘,每个盘上一个单词,必须重新排列磁盘使得每个单词的第一个字母与前一个单词的最后一个字母相同.给你一组单词问能不能排成上述形式. 思路 :把每个单词看成有首字母指向尾字母的有向边,每个字母看成一个点,题中要求等效于判断图中是否存在一条路径经过每一条一次且仅一次,就是有向欧拉通路.统计个顶点的出入度,如果每个点的出入度都相同,那就是欧拉回路,如果有两个奇数度,那就是欧拉通路,除此之外,都不能满足要求.还有别忘了判断是否连通,此时用到并查集,图中所有的边