P1525 关押罪犯 并查集

题目链接:https://www.luogu.org/problemnew/show/P1525

一道很难想到思路的题,还可以用二分图染色法,但我们只考虑并查集

要使得冲突最小,首先我们应该让冲突大的尽可能的不在同一个监狱

如果两个相互冲突的人都与第三个人冲突,那么应优先让冲突大的在不同的监狱

那么冲突小的冲突就是不可避免地冲突

如果整个过程都按照冲突的大小从大到小进行的话第一个不可避免的冲突就是将会发生的冲突中最大的一个

用并查集来实现的话,就是将敌人的敌人与自己放在同一个集合中,在同一个集合中的人发生的冲突就是无法避免的冲突

找到其中的最大值

整个过程要按冲突的大小顺序进行

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 struct edge{
 4     int from,to,cost;
 5 };
 6 edge G[100005];
 7 int f[20005];
 8 int e[20005];    //存储敌人
 9
10 bool cmp(edge a,edge b){
11     return a.cost>b.cost;
12 }
13
14 int fa(int a){
15     return f[a] == a?a:f[a] = fa(f[a]);
16 }
17
18 bool check(int a,int b){
19     return fa(a) == fa(b);
20 }
21
22 void link(int a,int b){
23     if(!check(a,b))
24         f[fa(a)] = fa(b);
25 }
26
27 int main()
28 {
29     int n,m;
30     cin>>n>>m;
31     for(int i=1;i<=n;++i)
32         f[i] = i;
33     for(int i=0;i<m;++i){
34         int a,b,c;
35         cin>>a>>b>>c;
36         G[i].from = a;
37         G[i].to = b;
38         G[i].cost = c;
39     }
40     sort(G,G+m,cmp);
41     for(int i=0;i<=m;++i){    //如果没有发生冲突i=m
42         edge ans = G[i];
43         if(check(ans.from,ans.to)){    //无法避免
44             cout<<ans.cost;
45             break;
46         }
47         else{
48             if(!e[ans.from])
49                 e[ans.from] = ans.to;
50             else
51                 link(ans.to,e[ans.from]);
52             if(!e[ans.to])
53                 e[ans.to] = ans.from;
54             else
55                 link(ans.from,e[ans.to]);
56         }
57     }
58     return 0;
59  } 

原文地址:https://www.cnblogs.com/liluan99/p/9217108.html

时间: 2024-07-31 15:45:01

P1525 关押罪犯 并查集的相关文章

洛谷P1525 关押罪犯 并查集

无冲突 输出 0 洛谷P1525 关押罪犯 并查集 用拆点法 将一个点拆成两份 一个点和 x 的朋友相连 一个点和 x的敌人相连 若 x 与 y 是敌人 因为只有两个阵营 所以满足敌人的敌人就是朋友 然后 x 连向 y 的敌人 y 连向 x 的敌人 因为这是双向边 所以 y的朋友就是x的敌人就不用连了 如果某一时刻 getfather(e[ i ].from)==getfather(e[ i ].to) 这说明两个点已经是敌人关系的两个人 通过朋友关系连上了 那就结束了 1 #include <

洛谷P1525关押罪犯——并查集

题目:https://www.luogu.org/problemnew/show/P1525 并查集+贪心,从大到小排序,将二人分在不同房间,找到第一个不满足的即为答案. 代码如下: #include<iostream> #include<cstdio> #include<algorithm> using namespace std; int n,m,fa[20005],ans,ct,d[20005]; struct N{ int hd,to,w; }edge[1000

NOIP2010关押罪犯[并查集|二分答案+二分图]

题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多.如果两名怨气值为c 的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并造成影响力为c 的冲突事件. 每年年末,警察局会将本年内监狱中的所有冲突事件按影响力从大到小排成一个列表,然后上报到S 城Z 市长那里.公务繁忙的Z 市长只会去看列表

[noip2010]关押罪犯 并查集

第一次看的时候想到了并查集,但是不知道怎么实现: 标解,f[i]表示i所属的集合,用f[i+n]表示i所属集合的补集,实现的很巧妙,可以当成一个使用并查集的范例: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<map> 6 #include<ctime> 7 #include<vector>

codevs 1069 关押罪犯 并查集

很有意思的一道题.刚开始看不出这是道并查集,后来看了题解才会做,就是把要分开的囚犯放在同个集合里,表示这两个囚犯不在同一间监狱,但不是直接合并,例如1和2要分开,则1和2’.1’和2合并(x’为x的虚点),同个集合中实点和虚点分属于两间监狱(即x’与y在不同监狱):再例如,1和2,2和3要分开,则1和2’合并,2’和3合并,那么1和3会在同一间监狱,1’和2合并,2和3’合并,那么2就在另一间监狱.这样一来整道题的思路就呼之欲出了:按仇恨值从大到小分开每对囚犯,若出现无法分开的情况(即已在同一个

洛谷 P1525 关押罪犯==codevs 1069 关押罪犯[NOIP 2010]

P1525 关押罪犯 513通过 1.4K提交 题目提供者该用户不存在 标签图论并查集NOIp提高组2010 难度普及+/提高 提交该题 讨论 题解 记录 最新讨论 咳咳.竟MLE了. 囧.运行时错误,错误编号-… 点2是何方神圣? 题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多.

做题记录:P1525 关押罪犯(洛谷)

P1525 关押罪犯 /*在这一道题中并查集的作用是:将同一个监狱里的罪犯合并到一起. 思路:将每对罪犯之间的怨气值从大到小排序,再依次把他们分到不 同的两个监狱里,当发现这一对罪犯已经在同一个监狱里时,就说明 他们已经不能再分开了(分开了就不是最优了).此时,这一对罪犯 之间的怨气值就是答案.值得注意的是,当没有冲突发生时,要记得 输出0.那么,我们应该如何用并查集实现以上的思路呢?首先说几个 关键词语的含义: 1."敌人":如果一对罪犯被分到两个不同的监狱里,那么他们就互为&quo

P1525 关押罪犯(二分图/并查集)

题意: 给你m对矛盾关系,每对关系分别涉及到x,y两人,矛盾值为w 请你判断分配x和y到两个集合中,能否避免冲突 如能避免请输出0,如果冲突不可避免,请输出最小的矛盾值 思路: 方法①:并查集 并查集能维护连通性.传递性,通俗地说,亲戚的亲戚是亲戚. 我们不妨这样想:两个人a,b有仇,那么把他们放在一起显然会打起来,那么我们还不如把a与b的其他敌人放在一起, 因为这样可能会出现“敌人的敌人就是朋友”的情况,恰好a与b的其他敌人之间没有矛盾,那么他们就可以放在同一个集合中,反之b对a亦然 我们可以

P1525 关押罪犯

题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多.如果两名怨气值为c 的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并造成影响力为c 的冲突事件. 每年年末,警察局会将本年内监狱中的所有冲突事件按影响力从大到小排成一个列表,然后上报到S 城Z 市长那里.公务繁忙的Z 市长只会去看列表