【洛谷P1525】[NOIP2010]关押罪犯

关押罪犯

题目链接

 

思路:

二分图或并查集

这里讲并查集算法:

  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\n",xw[i].data);
40             return 0;
41         }
42     }
43     cout<<0<<endl;
44     return 0;
45 }

 

@klxw

posted @ 2018-03-02 20:41  yjk  阅读(150)  评论(0)    收藏  举报