题意:
题解:
就是让最大的冲突最小。
我们从边权考虑,首先将边按边权从大到小排序,依次处理每一个边。我们尽量的使当前处理边权不出现,如果这个边权不可避免地一定会出现,那么最大值一定是当前处理的边权。
可以使用扩展域并查集来判断一个边是否是可以避免出现。
将一个点
拆分成两个点,
表示与
在同一个监狱的犯人,
表示不与
在同一个监狱的犯人。
在判断一条边是否可以避免时,假设这条边端点为
,权值为
。首先判断
和
是不是在一个集合,如果是则说明在避免前面的边的时候,已经将
放入一个集合中了,所以这条边无法避免,z就是答案。
否则,将
和
放入一个集合,
和
放入一个集合。表示和x同一个监狱的人跟不和y同一个监狱的人是一个监狱,和y同一个监狱的人跟 不和x同一个监狱的人 是一个监狱。保证
不是同一个监狱。
代码:
/**
* Author : Xiuchen
* Date : 2020-03-26-12.16.46
* Description : 关押罪犯
*/
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<cmath>
#include<math.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fLL;
const int maxn = 2e4 + 100;
int gcd(int a, int b){
return b ? gcd(b, a % b) : a;
}
int n, m;
int fa[maxn * 2];
struct node{
int a, b, c;
} edge[100100];
bool cmp(node a, node b){
return a.c > b.c;
}
int get(int x){
if(x == fa[x]) return x;
return fa[x] = get(fa[x]);
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= 2 * n; i++) fa[i] = i;
for(int i = 1; i <= m; i++)
scanf("%d%d%d", &edge[i].a, &edge[i].b, &edge[i].c);
sort(edge + 1, edge + 1 + m, cmp);
int ans = 0;
for(int i = 1; i <= m; i++){
int x_0 = edge[i].a, x_1 = edge[i].a + n;
int y_0 = edge[i].b, y_1 = edge[i].b + n;
if(get(x_0) == get(y_0) || get(x_1) == get(y_1)){
ans = edge[i].c;
break;
}
else{
fa[get(x_1)] = get(y_0);
fa[get(x_0)] = get(y_1);
}
}
printf("%d\n", ans);
return 0;
}