关押罪犯
思路:
二分图或并查集
这里讲并查集算法:
1.将每对罪犯的冲突关系按影响从大到小排序
2.将集合与(i+n)合并表示编号为i的罪犯不能在该集合内
3.依次从大到小处理冲突关系:
若x与y+n、y与x+n不在同一个集合内,将集合find(x)与集合find(y+n)合并,将集合find(x+n)与集合find(y)合并;
反之,则发生了冲突,退出循环,当前罪犯的怨气值即为最小的冲突影响
贴代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int n,m,fa[400010]; 7 int find(int x) 8 { 9 if(fa[x]!=x) fa[x]=find(fa[x]); 10 return fa[x]; 11 } 12 void unionn(int x,int y) 13 { 14 int fx=find(x),fy=find(y); 15 fa[fx]=fy; 16 } 17 struct w{ 18 int l; 19 int r; 20 int data; 21 } xw[500010]; 22 bool cmp(w x,w y) 23 { 24 return x.data>y.data; 25 } 26 int main() 27 { 28 scanf("%d%d",&n,&m); 29 for(int i=1;i<=2*n;i++) 30 fa[i]=i; 31 for(int i=1;i<=m;i++) 32 scanf("%d%d%d",&xw[i].l,&xw[i].r,&xw[i].data); 33 sort(xw+1,xw+1+m,cmp); 34 for(int i=1;i<=m;i++) 35 { 36 unionn(xw[i].l,xw[i].r+n); 37 unionn(xw[i].l+n,xw[i].r); 38 if(find(xw[i].l)==find(xw[i].l+n)||find(xw[i].r+n)==find(xw[i].r)) { 39 printf("%d ",xw[i].data); 40 return 0; 41 } 42 } 43 cout<<0<<endl; 44 return 0; 45 }
@klxw