【扩展域】 关押罪犯

传送门

题意

一共两座监狱,\(n\)个罪犯编号为\(1\sim n\),两个罪犯之间有怨气值\(c\),如果处在同一个监狱,就会爆发值为\(c\)的冲突
给出\(m\)对怨气值,分别安排在着两座监狱,使得满足关系并且最大的怨气值最小,如果不存在冲突就输出\(0\)

数据范围

\(N \leq 20000, M \leq 100000\)

题解

一共两座监狱关系明显具有传递性,贪心,按照怨气值从大到小排序,如果当前已经在同一个监狱直接输出即可
将每个\(lx\)表示为不和\(x\)在一个集合,\(ly\)表示不和\(y\)在一个集合的,如果无冲突即两个人可以安排到不同监狱,合并

Code

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>a;i--)
const int N=1e5+10;
int n,m;
int fa[N];
struct node {
    int x, y;
    int c;
    bool operator<(const node x) {
        return c > x.c;
    }
}e[N];

int find(int x) {
    if(fa[x] == x) return x;
    return fa[x] = find(fa[x]);
}
int main() {
    cin>>n>>m;
    rep(i, 0, 2 * n + 1) fa[i] = i;
    rep(i, 1, m + 1) cin>>e[i].x>>e[i].y>>e[i].c;

    sort(e + 1, e + m + 1);
    rep(i, 1, m + 1) {
        int x = find(e[i].x),lx=find(e[i].x+n);
        int y = find(e[i].y),ly=find(e[i].y+n);

        if(find(x) == find(y)) {
            cout<<e[i].c<<endl;
            return 0;
        }
        fa[x] = ly;
        fa[y] = lx;
    }
    cout<<"0"<<endl;
}
posted @ 2020-10-02 15:40  Hyx'  阅读(147)  评论(0编辑  收藏  举报