洛谷P1525 关押罪犯 贪心+并查集

题目链接:https://www.luogu.com.cn/problem/P1525

题目要求使发生的冲突影响力最大的最小,这里用贪心+并查集,将所有可能发生的冲突按影响力从大到小排序,每次从中挑最大的,将两个人安排到不同监狱。用并查集判断两人是否在同一监狱,如果已在同一监狱,输出这个冲突的影响力大小。否则,将他划到对方仇人的那个监狱。注意要加一个enemy数组记录仇人。
代码如下

#include <bits/stdc++.h>
using namespace std;
const int inf=0x7fffffff;
const int maxn=2e4+5;
const int maxm=1e5+5;
struct node
{
    int from,to,value;
}p[maxm];
int fa[maxn],enemy[maxn];//祖先数组与仇人数组
int n,m;
int find(int x)//并查集找祖先
{
    if(fa[x]==x)
    return x;
    return fa[x]=find(fa[x]);
}
bool cmp(node a,node b)
{
    return a.value>b.value;
}
int main()
{
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
    fa[i]=i;//初始祖先节点都是自己
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d %d",&p[i].from,&p[i].to,&p[i].value);
    }
    sort(p+1,p+1+m,cmp);
    for(int i=1;i<=m;i++)
    {
        int x=p[i].from,y=p[i].to,c=p[i].value;
        if(find(x)==find(y))//已在同一监狱,输出答案
        {
            printf("%d\n",c);
            return 0;
        }
        if(!enemy[x])
        enemy[x]=y;
        else//将y归到x仇人的监狱
        fa[find(enemy[x])]=find(y);
        if(!enemy[y])
        enemy[y]=x;
        else//同上
        fa[find(enemy[y])]=find(x);
    }
    puts("0");//没有冲突
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44491423/article/details/104481871