[题解]关押罪犯

Posted czy--blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[题解]关押罪犯相关的知识,希望对你有一定的参考价值。

原题链

主要算法:并查集

主要思路:

先用结构体将每一对罪犯的怨气值储存,再用怨气值为关键词从大到小排序。现在,为了让事情的影响最小,我们需要让怨气值最大的一对罪犯不在同一个监狱,所以在从大到小的顺序合并的时候是:

merge(a[i].x,a[i].y + n);
merge(a[i].y,a[i].x + n)

那么,如果在一次合并时,我们发现有两个我们将要合并的人已经在另一个集合里了时就可以输出这时的罪犯$i$的怨气值及时结果。因为我们是从怨气值最大的时候往后操作,那么如果我们要将两个罪犯重新拆开重新合并的话,时间的影响值就会增加, 答案就不能保证最优。

源代码

#include <bits/stdc++.h>
using namespace std;
struct node{
    int x,y;
    int w;
}a[100010];
bool cmp(node c,node d){
    return c.w > d.w;
}
int fa[200010];
int get(int x){
    if(fa[x] == x)return x;
    return fa[x] = get(fa[x]);
}
void merge(int x,int y){
    fa[get(x)] = get(y);
    return;
}
int main(){
    int n,m;
    cin>>n>>m;
    for(int i = 1;i <= 2 * n;i++)fa[i] = i;
    for(int i = 1;i <= m;i++){
        cin>>a[i].x>>a[i].y>>a[i].w;
    }
    sort(a + 1,a + m + 1,cmp);
    for(int i = 1;i <= m;i++){
        if(get(a[i].x) == get(a[i].y)){cout<<a[i].w<<endl;exit(0);}
        merge(a[i].x,a[i].y + n); 
        if(get(a[i].y) == get(a[i].x)){cout<<a[i].w<<endl;exit(0);}
        merge(a[i].y,a[i].x + n);
    }
    cout<<0<<endl;
    return 0;
}

以上是关于[题解]关押罪犯的主要内容,如果未能解决你的问题,请参考以下文章

[题解]关押罪犯

P1525 关押罪犯 题解

P1525 关押罪犯 题解

P1525 关押罪犯 题解

题解P1525 关押罪犯

1069 关押罪犯