F. Make It Connected(krustra+)

本文解析了Codeforces比赛中的F题,介绍了如何通过找到权值最小的点并使用Kruskal算法来解决图的最小生成树问题,实现图的联通最小花费。

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

题目链接:http://codeforces.com/contest/1095/problem/F

 题目大意:首先给你n个点,然后给你每个点的权值,再给你m条边,这些边可以选也可以不选,然后问你要使这个加边构成的图联通的最小花费。

 具体思路:我们可以先找出权值最小的点,然后别的点都向向这个点连一条边,这是当前使得图联通的最小构图的方法,然后再看一下题目给定的点加上,注意题目给定的权值不一定是最小的。(如果是用spfa算法的话,就需要建立双向边,然后用krustra的话,没有建立双向边的必要,建立起来就可以了)

AC代码:

#include <iostream>
#include<stdio.h>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
# define ll long long
# define LL_inf 1ll<<60
const int maxn  =4e5+10;
struct node
{
    int fr;
    int to;
    ll cost;
} q[maxn];
ll a[maxn];
int father[maxn],num;
int Find(int t)
{
    return t==father[t]?t:father[t]=Find(father[t]);
}
bool cmp(node t1,node t2)
{
    return t1.cost<t2.cost;
}
ll krustra()
{
    ll sum=0;
    for(int i=1; i<=num; i++)
    {
        int t1=Find(q[i].fr);
        int t2=Find(q[i].to);
        if(t1!=t2)
        {
            father[t1]=t2;
            sum+=q[i].cost;
        }
    }
    return sum;
}
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    ll minn=LL_inf;
    int id=0;
    for(int i=1; i<=n; i++)
    {
        father[i]=i;
        scanf("%lld",&a[i]);
        if(a[i]<minn)
        {
            minn=a[i];
            id=i;
        }
    }
    int st,ed;
    ll co;
    for(int i=1; i<=m; i++)
    {
        scanf("%d %d %lld",&st,&ed,&co);
        co=min(a[st]+a[ed],co);
        q[++num].fr=st;
        q[num].to=ed;
        q[num].cost=co;
    }
    for(int i=1; i<=n; i++)
    {
        if(i==id)
            continue;
        q[++num].fr=i;
        q[num].to=id;
        q[num].cost=a[i]+a[id];
    }
    sort(q+1,q+num+1,cmp);
    ll ans=krustra();
    printf("%lld\n",ans);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值