hdu6081 度度熊的王国战略(并查集处理连通图问题)

解决一道HDU 6081题目,通过并查集判断连通图,并找出使图变为非连通状态所需的最少边数移除。涉及并查集实现及图论相关知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6081

题目大意:给你一个连通图,你可以减掉一些连通分量,让它变为非连通图,输出去掉多少连通分量(最少),图为非连通图

题目思路:

    一、首先你要确定该图是连通图,如果不是则输出0,图内一共有N个点,那么根据并查集的性质,会有N-1个点并入到某一个点为根节点的集合中去,所以设Cnt=N-1,每次合并的时候Cnt--;

    二、Sum[i]数组存储每个点的连通值,即每个点与其他点连接时的权值的和(千万要记住自己与自己链接的权值不要加和)

    三、如果所有的边权都输入了,不是连通图输出0,是连通图,遍历每一个点的Sum值,输出最小的Sum值

题目坑点:同一个点的权值不要加和!!!!这个题目一个点一个点的撕就可以,可能是因为数据弱的原因。

学到的东西:并查集的运用:N个点合并N-1次,则为连通图。做图论相关的题目,一定要讨论两点相同的情况。

代码:

#include <bits/stdc++.h>
using namespace std;

const int maxn = 3005;
const int inf = 0x3ffffff;
int pre[maxn];
int sum[maxn];

void build(int n)
{
    for(int i=0;i<=n;i++)
        pre[i]=i,sum[i]=0;
}

int find(int x)
{
    int p,tmp;
    p=x;
    while(x!=pre[x]) x=pre[x];
    while(p!=x){
        tmp=pre[p];
        pre[p]=x;
        p=tmp;
    }

    return x;
}

bool join(int x,int y)
{
    int p=find(x);
    int q=find(y);
    if(p!=q){
        pre[p]=q;
        return true;
    }
    return false;
}


int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        int cnt=n-1;
        build(n);
        while(m--){
            int x,y,val;
            scanf("%d%d%d",&x,&y,&val);
            if(x==y) continue;//如果是同一个点,就没有处理的必要性了
            sum[x]+=val,sum[y]+=val;
            if(join(x,y)) cnt--;
        }

        if(cnt!=0) printf("0\n");
        else{
            int mmin=inf;
            for(int i=1;i<=n;i++)
                if(sum[i]<mmin) mmin=sum[i];

            printf("%d\n",mmin);
        }
    }
    return 0;
}


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值