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; }