您的位置:首页 > 其它

NOIP2010 提高组 复赛 prison 关押罪犯

2017-06-20 22:31 411 查看
NOIP2010  提高组 复赛 prison 关押罪犯

//P1525 关押罪犯

//代码角度来说,这篇文章写得比较漂亮http://hzwer.com/599.html

//该题用并查集的核心是,敌人的敌人是朋友。

//e[i].a+n表示e[i].a的对立面,属不同的两个集合,而该问题中一共两个集合。

//f[e[i].a+n] 与 f[e[i].a]爸爸不同。

//看懂他人代码比较关键的一条是:带入输入数据进行手动模拟。该题收获之一。

//该题收获之二,集合合并原来可以写得这么简洁。

#include <stdio.h>

#include <string.h>

int f[20000*2+100];

struct node{

    int a,b,c;

}e[100000+100],e_t;

void quicksort(int left,int right){//快排,从大到小

    int i=left,j=right,mid=e[(left+right)/2].c;

    while(i<=j){

        while(e[i].c>mid)

            i++;

        while(e[j].c<mid)

            j--;

        if(i<=j){

            e_t=e[i];

            e[i]=e[j];

            e[j]=e_t;

            i++;

            j--;

        }

    }

    if(left<j)

        quicksort(left,j);

    if(i<right)

        quicksort(i,right);

}

int getf(int u){//找爸爸

    if(f[u]==u)

        return f[u];

    f[u]=getf(f[u]);

    return f[u];

}

int main(){

    int n,m,i,j,f1,f2;

    scanf("%d%d",&n,&m);

    for(i=1;i<=2*n;i++)

        f[i]=i;

    for(i=1;i<=m;i++)

        scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].c);

    quicksort(1,m);

    for(i=1;i<=m;i++){

        f1=getf(e[i].a);

        f2=getf(e[i].b);

        if(f1==f2){

            printf("%d\n",e[i].c);

            return 0;

        }

        f[f2]=getf(e[i].a+n);//合并集合 ,敌人的敌人是朋友

        f[f1]=getf(e[i].b+n);

    }

    printf("0\n");

    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: