• 「BZOJ1232」 [Usaco2008Nov]安慰奶牛cheer


    「BZOJ1232」 [Usaco2008Nov]安慰奶牛cheer

    problem

    Solution

    最终的图显然是一棵树

    把每条边视作两条有向边。在树的情况下,一定需要走完所有的有向边。除了出发点以外,走一条有向边((u,v))对答案的贡献为(w(u,v)+c[v]),亦即每条无向边对答案的贡献为(w(u,v)*2+c[u]+c[v]),将其作为边权跑最小生成树。生成树的权值加上最小的点权即为答案

    Code

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #define maxn 10005
    #define maxm 100005
    using namespace std;
    typedef long long ll;
     
    int n,m;
    int c[maxn];
    int ans;
     
    struct edge
    {
        int u,v,w;
    }g[maxm];
     
    int prt[maxn];
     
    int getroot(int u)
    {
        return prt[u]==u?u:prt[u]=getroot(prt[u]);
    }
     
    bool cmp(const edge &a,const edge &b)
    {
        return a.w<b.w;
    }
     
    void Kruskal()
    {
        for(register int i=1;i<=n;++i)
            prt[i]=i;
        sort(g+1,g+m+1,cmp);
        int cnt=0;
        for(register int i=1;i<=m;++i)
        {
            int r1=getroot(g[i].u),r2=getroot(g[i].v);
            if(r1!=r2)
            {
                prt[r1]=r2;
                ++cnt;
                ans+=g[i].w;
            }
            if(cnt==n-1)
                return;
        }
    }
     
    int main()
    {
        scanf("%d%d",&n,&m);
        for(register int i=1;i<=n;++i)
            scanf("%d",&c[i]);
        for(register int i=1;i<=m;++i)
        {
            scanf("%d%d%d",&g[i].u,&g[i].v,&g[i].w);
            g[i].w=g[i].w*2+c[g[i].u]+c[g[i].v];
        }
        Kruskal();
        sort(c+1,c+n+1);
        printf("%d",ans+c[1]);
        return 0;
    }
    
  • 相关阅读:
    ubuntu1604安装微信
    python中汉字 hash值
    python-json
    lvm 扩展目录大小
    python数据可视化编程实战
    python-数据分析
    爬虫学习路径
    415. 字符串相加-字符串-简单
    43. 字符串相乘-字符串-中等难度
    44. 通配符匹配-动态规划-困难
  • 原文地址:https://www.cnblogs.com/lizbaka/p/10505662.html
Copyright © 2020-2023  润新知