AC通道:http://codevs.cn/problem/1069/
[分析]
可以发现,因为市长只会关心冲突事件影响力的最大值,所以无论你怎么把罪犯们分开,只要冲突事件影响力最大的那两个人还在同一所监狱,冲突事件影响力的最大值就不会改变。所以我们可以采取贪心的思想,每次将冲突事件影响力最大的两个人分开,直到这两个人根据前面的条件,已经分不开了,那么最大值就是他们所能产生的影响力的最大值。
因为“分开”这个操作不好实现,所以我们设,若A,B两个人分开,那么A,B‘就在同一所监狱中,及A,B’在同一个集合中。将影响力按从大到小的顺序排个序,每次分开两个人A,B,都将A,B‘合并,A’,B合并。若分开A,B时,发现A,B已经在同一个集合中,那么就直接输出它们影响力的值。
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct Edge{
int l,r,w;
bool fl;
};
bool cmp(const Edge a,const Edge b){
return a.w>b.w;
}
int n,m;
int fa[40010];
Edge edge[200010];
bool flag;
inline int find(int x){
int tmp=x,nxt;
while(tmp!=fa[tmp])tmp=fa[tmp];
while(x!=tmp){
nxt=fa[x];
fa[x]=tmp;
x=nxt;
}
return tmp;
}
inline void merge(int x,int y){
int fx=find(x),fy=find(y);
fa[fx]=fy;
}
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].l,&edge[i].r,&edge[i].w);
edge[i].fl=true;
if(edge[i].w)flag=true;
}
if(!flag||n==2){
printf("0");
}
sort(edge+1,edge+1+m,cmp);
for(int i=1;i<=m;i++){
if(find(edge[i].l)==find(edge[i].r)){
printf("%d\n",edge[i].w);
return 0;
}
else{
merge(edge[i].l,edge[i].r+n);
merge(edge[i].l+n,edge[i].r);
}
}
return 0;
}