【扩展域】 关押罪犯
传送门
题意
一共两座监狱,\(n\)个罪犯编号为\(1\sim n\),两个罪犯之间有怨气值\(c\),如果处在同一个监狱,就会爆发值为\(c\)的冲突
给出\(m\)对怨气值,分别安排在着两座监狱,使得满足关系并且最大的怨气值最小,如果不存在冲突就输出\(0\)
数据范围
\(N \leq 20000, M \leq 100000\)
题解
一共两座监狱关系明显具有传递性,贪心,按照怨气值从大到小排序,如果当前已经在同一个监狱直接输出即可
将每个\(lx\)表示为不和\(x\)在一个集合,\(ly\)表示不和\(y\)在一个集合的,如果无冲突即两个人可以安排到不同监狱,合并
Code
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>a;i--)
const int N=1e5+10;
int n,m;
int fa[N];
struct node {
int x, y;
int c;
bool operator<(const node x) {
return c > x.c;
}
}e[N];
int find(int x) {
if(fa[x] == x) return x;
return fa[x] = find(fa[x]);
}
int main() {
cin>>n>>m;
rep(i, 0, 2 * n + 1) fa[i] = i;
rep(i, 1, m + 1) cin>>e[i].x>>e[i].y>>e[i].c;
sort(e + 1, e + m + 1);
rep(i, 1, m + 1) {
int x = find(e[i].x),lx=find(e[i].x+n);
int y = find(e[i].y),ly=find(e[i].y+n);
if(find(x) == find(y)) {
cout<<e[i].c<<endl;
return 0;
}
fa[x] = ly;
fa[y] = lx;
}
cout<<"0"<<endl;
}