返回顶部

洛谷 P1525 关押罪犯 (贪心,扩展域并查集)

  • 题意:有\(n\)个罪犯,\(m\)对罪犯之间有仇,现在将这些罪犯分到两个监狱里去,问两个监狱里有仇罪犯之间的最大权值最小为多少.

  • 题解:先按边权从大到小排序,然后贪心,边权大的两个罪犯,我们一定要先让他们两人分到不同的监狱中,这里我们就可以用并查集来维护, 用种类并查集每次维护两个罪犯的关系,如果他们不在同一集合,就将他们合并到两个不同的集合,

    如果他们在同一个集合,那么就直接输出他们的权值.

  • 代码:

    #include <iostream>
    #include <iomanip>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <map>
    #include <set>
    #include <unordered_set>
    #include <unordered_map>
    #define ll long long
    #define db double
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    #define per(a,b,c) for(int a=b;a>=c;--a)
    const int N = 1e6 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
    int gcd(int a,int b){return b?gcd(b,a%b):a;}
    int lcm(int a,int b){return a/gcd(a,b)*b;}
    
    inline int read()
    {
        int X=0; bool flag=1; char ch=getchar();
        while(ch<'0'|ch>'9') {if(ch=='-') flag=0; ch=getchar();}
        while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
        if(flag) return X;
        return ~(X-1);
    }
    
    struct misaka{
        int x,y,val;
        bool operator < (const misaka & mikoto) const{
            return val>mikoto.val;
        }
    }e[N];
    
    int n,m;
    int p[N];
    
    int find(int x){
        if(p[x]!=x) p[x]=find(p[x]);
        return p[x];
    }
    
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
        cin>>n>>m;
    
        rep(i,1,m){
            cin>>e[i].x>>e[i].y>>e[i].val;
        }
    
        sort(e+1,e+1+m);
    
        rep(i,1,2*n+10) p[i]=i;
    
        rep(i,1,m){
            int x=e[i].x;
            int y=e[i].y;
            if(p[find(x)]==p[find(y)] || p[find(x+n)]==p[find(y+n)]){
                cout<<e[i].val<<'\n';
                return 0;
            }
            p[find(x)]=p[find(y+n)];
            p[find(x+n)]=p[find(y)];
        }
    
        cout<<0<<'\n';
    
        return 0;
    }
    
    
    
posted @ 2020-11-13 01:34  Rayotaku  阅读(74)  评论(0编辑  收藏  举报