P1525 [NOIP2010 提高組] 關押罪犯

黑屿白發表於2024-05-03

原題連結

題解

這題我採用了帶權並查集的做法,0代表兩囚犯處於監獄,1代表兩囚犯不同監獄。

根據題意,我們想讓衝突值儘可能的小,那麼我們要先把仇恨值大的兩罪犯放在不同監獄;即按仇恨值從大到小的去判斷每條仇恨資訊。(貪心思想)

code

#include<bits/stdc++.h>
using namespace std;
const int N=2e4+5;
const int M=1e5+5;
int father[N],dis[N];
int n,m;
struct Node{
    int one,two,value;
};
Node a[M];
void build(){
    for (int i=1;i<=n;i++) father[i]=i;
}
int find(int x){
    if (x==father[x]) return x;
    int r=find(father[x]);
    dis[x]=(dis[x]+dis[father[x]])%2;
    father[x]=r;
    return r;
}
bool cmp(Node a,Node b){
    return a.value>b.value;
}
int main(){
    cin>>n>>m;
    build();
    for (int i=1;i<=m;i++) cin>>a[i].one>>a[i].two>>a[i].value;
    sort(a+1,a+m+1,cmp);
    bool bol=true;
    for (int i=1;i<=m;i++){
        int fx=find(a[i].one),fy=find(a[i].two);
        if (fx==fy && dis[a[i].one]==dis[a[i].two]){
            cout<<a[i].value<<endl;
            bol=false;
            break;
        }
        else if (fx!=fy){
            dis[fx]=(dis[a[i].two]+1-dis[a[i].one]+2)%2;
            father[fx]=fy;
        }
    }
    if (bol) cout<<0<<endl;
    return 0;
}

相關文章