P1525 关押罪犯 并查集
Posted liluan99
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
以上是关于P1525 关押罪犯 并查集的主要内容,如果未能解决你的问题,请参考以下文章