修路

来源:互联网 发布:淘宝童装名字大全 编辑:程序博客网 时间:2024/04/30 00:25

题解

这里写图片描述

分析

因为每个城市的贡献度为a[i]i,实际上就是指它的出度或入度的个数,每一个出度或入度,它都会有贡献值a[i]
那么,也就是给连接它的边减去a[i]
所以,对于一条边xy,就把它的花费减去a[x]+a[y].
然后跑一边最小生成树就可以了。

#include <cmath>#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <queue>const long long maxlongint=2147483647;const long long mo=1000000007;const long long N=100005;using namespace std;long long a[N],n,m,ans,fa[N];struct ddx{    long long x,y,cost;}b[N];bool cmp(ddx x,ddx y){    return x.cost<y.cost;}long long get(long long x){    if(x==fa[x]) return x;    fa[x]=get(fa[x]);    return fa[x];}int main()                                 {                                        scanf("%lld%lld",&n,&m);             for(int i=1;i<=n;i++) fa[i]=i;    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);    for(int i=1;i<=m;i++)    {        scanf("%lld%lld%lld",&b[i].x,&b[i].y,&b[i].cost);        b[i].cost-=a[b[i].x]+a[b[i].y];    }    sort(b+1,b+m+1,cmp);    for(int k=0,i=1;i<=m && k<n-1;i++)    {        int x=get(b[i].x),y=get(b[i].y);        if(x!=y)        {            fa[x]=y;            ans+=b[i].cost;        }    }    printf("%lld",ans);}                                          
1 0
原创粉丝点击