1、本题用并查集做,将边从大到小排序,然后看两个端点是否在同一个集合中,如果在同一个集合就输出(贪心法),如果不在同一个集合,或至少有一个还没有分配,则他们两个分配到对立的监狱,注意后面应用find,而不是f[],因为a[i].y+n的集合可能已经在前几轮中被修改过。
#include<cstdio>
#include<algorithm>
using namespace std;
struct edge{
int x,y,w;
bool operator <(const edge &obj)const{
return w>obj.w;
}
}a[100010];
int f[40010];
int find(int x){
return f[x]==x?x:f[x]=find(f[x]);
}
int main(){
freopen("prison.in","r",stdin);
freopen("prison.out","w",stdout);
int n,m;
while(scanf("%d%d",&n,&m)==2){
bool flag=false;
for(int i=0;i<m;i++)
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);
sort(a,a+m);
for(int i=1;i<=n*2;i++)
f[i]=i;
for(int i=0;i<m;i++){
int x=find(a[i].x),y=find(a[i].y);
if(x==y) {printf("%d\n",a[i].w);flag=true;break;}
f[x]=find(a[i].y+n);
f[y]=find(a[i].x+n);
}
if(!flag)
printf("%d\n",0);
}
return 0;
}