洛谷p1525關押罪犯

原題

挺有意思的一道題。

大多數人思路應該是貪心,將犯罪值有大到小排,將兩個人放在兩個並查集中,如果他們在同一個並查集就退出。這樣你畫一下樣例就明白了,這兩個人的確放在兩棟樓,但是具體哪個人放在哪棟樓效果是不同的,而你要確定的話又需要枚舉一遍,超時妥妥的。

兩個互爲敵人的位置無法確定,但是很明顯還是要用並查集的。

敵人的敵人呢?他們是不是一定在同一棟樓?(貪心思想)

所以每次可以確定在一個並查集的是敵人的敵人,如果一個人沒有敵人,這個人就沒有用了。當敵人的敵人有矛盾時,就是最優解。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iomanip>
using namespace std;
int n,m,father[40009];bool vis[20009];
struct node{
    int l,r,data;
}a[100007];
int cmp(node a,node b)
{
    return a.data>b.data;
}
int find(int x)
{
    if(father[x]==x) return x;
    return father[x]=find(father[x]);
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n*2;++i)
    father[i]=i;
    for(int i=1;i<=m;++i)
    cin>>a[i].l>>a[i].r>>a[i].data;
    sort(a+1,a+m+1,cmp);
    for(int i=1;i<=m;++i)
    {
        if(find(a[i].l)==find(a[i].r))
        {
            
                cout<<a[i].data;
                return 0;
        }
        else
        {
            int fx=find(a[i].l),fy=find(a[i].r);
            father[fx]=find(a[i].r+n);
            father[fy]=find(a[i].l+n);
        }
    }
    cout<<"0";
    return 0;
} 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章