P1525 关押罪犯

  就是一道很简单的并查集,其实写完用不了多少时间。

  但有几个地方需要注意:

    1.我们不能把集合想想成两个监狱集合,而是储存一个enemy,否则会出现一个问题:

      当我们新枚举两个犯人时,如果这两个犯人都没有出现过,我们就不知道应该把这两个人放在哪,而且这个放法一定会对之后的结果造成影响,所以必须要enemy数组,进行转换。

    2.就是对于0的输出……

  另外这是道贪心,因为我们要尽可能地把两个仇恨值大的犯人分开。

  代码:

#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 100005
int enemy[maxn];
struct node
{
    int x,y,c;    
} q[maxn];
int n,m,ans,par[maxn];
bool cmp(node a,node b)
{
    return a.c>b.c;
}
int find(int x)
{
    return x ==par[x] ? x : par[x]=find(par[x]); 
}
void merge(int x,int y)
{
    par[find(x)]=find(y);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        par[i]=i;
    for(int i=1;i<=m;i++)
    scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].c);
    sort(q+1,q+1+m,cmp);
    for(int i=1;i<=m;i++)
    {
        if(find(q[i].x)==find(q[i].y))
        {
            ans=q[i].c;
            break;
        }
        else
        {
            if(enemy[q[i].x]==0)
                enemy[q[i].x]=q[i].y;
            else
                merge(q[i].y,enemy[q[i].x]);
            if(enemy[q[i].y]==0)
                enemy[q[i].y]=q[i].x;
            else
                merge(q[i].x,enemy[q[i].y]);
        }
    }
    printf("%d",ans);
    return 0; 
}

 

posted @ 2018-12-01 16:57  paopo  阅读(135)  评论(0编辑  收藏  举报