CODEVS 1069关押罪犯

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct node {
    int u,v,value;
}a[400000];
int cmp(struct node aa,struct node bb){
    return aa.value>bb.value;
}
int n,m,fa[50000],k=0;
int find(int x){
    return fa[x]==x?x:fa[x]=find(fa[x]);
}
int main(){

    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++) scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].value);
    sort(a+1,a+m+1,cmp);
    for(int i=1;i<=n*2;i++) fa[i]=i;//避免死循环
    for(int i=1;i<=m;i++){
        int p=find(a[i].v);
        int q=find(a[i].u);
        if(p==q){
            printf("%d",a[i].value);
            k=1;
            break;
        }
        else{
            fa[p]=find(a[i].u+n);//在下一个集合中互相立为敌人
            fa[q]=find(a[i].v+n);//在下一个集合中互相立为敌人
        }
    }
    if(k==0) printf("0");
    return 0;
}

引用题解:
总共只有两个集合,想一下这样的逻辑关系,a不和b在一起,a不和c在一起,那么b和c一定在一起。
将 i 的所有敌人放到fa[i]所指向的并查集中,在这里需要考虑一个问题,如果1和2互为敌人,而将fa[1]指向2、fa[2]指向1,那么会导致在并查集查找中出死循环。那么可以使用一种处理方法,将fa[i]指向fa[n+i]。
初始化时将所有的道路从大到小排序,优先处理影响力大的冲突。如果这个冲突不可以被解决,那么这个影响力一定是无法被解决的最大值。a[i]为正在处理的冲突,a[i].v和a[i].u为要发生的冲突的两人,而fa[a[i].v]和fa[a[i].u]分别为v和u的敌人,按照原有的想法,两人的敌人应该都不相同,这样两人才能被关入不同的监狱,但如果a和b有相同的敌人,显然并不能解决冲突。
在初始化时还存在一个问题,并不可以在初始的时候就将fa[i]指向fa[n+i]。因为当f[i]并没有和f[n+i]相连时,i节点相对独立,到i节点第一次出现时,这个冲突一定可以被解决,即i一定可以被关进某个监狱,但如果f[i]已经指向f[n+i],那么便有这个冲突无法被解决的可能。
引用题解 传送门 (点我)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值