BZOJ 1232 安慰奶牛题解

题目传送门:BZOJ 1232

这是一个边权和点权结合在一起的题,但是因为要从当前点出发并回到原点,所以每个边都被经过了两次,节点至少被经过一次,所以我们将边权重新赋值,所以推出

 

那么遍历之后,并不是最终结果,我们有个根节点未选择,所以对于当前这个树,我们可以寻找一个最小的点权来作为根节点,那么他会被多经过一次,加上即使最后答案;

所以就是修改边权跑最小生成树;

这里我作了kruskal做法:

#include<bits/stdc++.h>
using namespace std; int a[10001]; struct edge { int l,r,v; } e[100001]; int f[10001]; bool cmp(edge a,edge b) { return a.v<b.v; } int n,ans; int find(int n) { if(f[n]==n) return n; f[n]=find(f[n]); return f[n]; } void bing(int m,int n) { int x,y; x=find(m); y=find(n); f[x]=y; } int main() { int p,num=0,k=0,s=0x7fffffff; scanf("%d%d",&n,&p); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); s=min(s,a[i]); } for(int i=1;i<=p;i++) { num++; scanf("%d%d%d",&e[num].l,&e[num].r,&e[num].v); e[num].v=e[num].v*2+a[e[num].l]+a[e[num].r]; } sort(e+1,e+num+1,cmp); for(int i=1;i<=n;i++) f[i]=i; for(int i=1;k<n-1;i++) { if(find(e[i].l)!=find(e[i].r)) { ans+=e[i].v; bing(e[i].l,e[i].r); k++; } } printf("%d",ans+s); return 0; }

转载于:https://www.cnblogs.com/Tyouchie/p/10366912.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值