首页 > 其他 > 详细

BZOJ 1232 安慰奶牛题解

时间:2019-02-12 20:56:40      阅读:164      评论:0      收藏:0      [点我收藏+]

题目传送门: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;
}

BZOJ 1232 安慰奶牛题解

原文:https://www.cnblogs.com/Tyouchie/p/10366912.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!