关押罪犯(并查集维护二分图)
关押罪犯(并查集维护二分图)
题意:n个犯人与m对关系,每对关系的值表示仇恨值,将犯人分在两和监狱,如两个犯人间有关系且在相同的监狱就会共享仇恨值,求合理分配犯人后最低的仇恨值。
题解:此题考察的是用并查集构造二分图,先将关系的仇恨值由大到小排序,然后枚举关系,例如u,v,c分别表示两个犯人和仇恨值,如果u和v的祖宗不同,说明它们现在不在一个监狱,那么我们可以将u与v+n连边,u+n与v连边,(n+v表示非v,即u与v不在一个监狱,之后祖宗相同的情况是因为某点要与v不在一个监狱故与v+n连边,所以与u是同一个祖宗)
#include<iostream>
#include<algorithm>
using namespace std;
struct madoka{
int u,v,c;
}ma[100007];
bool cmp(madoka a1,madoka a2){
return a1.c>a2.c;
}
int n,m,u,v,c;
int fa[40007];
int fin(int p){
if(fa[p]==p)return p;
else{
return fa[p]=fin(fa[p]);
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n*2;i++){
fa[i]=i;
}
for(int i=1;i<=m;i++){
scanf("%d%d%d",&ma[i].u,&ma[i].v,&ma[i].c);
}
sort(ma+1,ma+1+m,cmp);
int ans=0;
for(int i=1;i<=m;i++){
if(fin(ma[i].u)!=fin(ma[i].v)){
fa[fin(ma[i].u)]=fin(ma[i].v+n);
fa[fin(ma[i].u+n)]=fin(ma[i].v);
}
else{
ans=ma[i].c;
break;
}
}
printf("%d\n",ans);
}