• [USACO08NOV]安慰奶牛Cheering up the Cow


    这个题一看就是最小生成树,但是这题关键是确定边权。

    首先为了安慰奶牛,一定要遍历每个奶牛并且回到起点,所以每条边会被经过两次,而为了通过这条边必须和两端点奶牛谈话,因此要再加上两端点的c值。综上(i,j)边权为l(i,j)  * 2 + c_i + c_j。

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define N 10010
    #define M 10000000
    using namespace std;
    int n,m;
    struct qwq
    {
        int x,y,val;
        bool operator < (const qwq &a) const
        {
            return val < a.val;
        }
    }e[M];
    int fa[N],siz[N];
    int find(int x)
    {
        if(fa[x] != x) fa[x] = find(fa[x]);
        return fa[x];
    }
    void merge(int x,int y)
    {
        if(siz[x] > siz[y]) swap(x,y); 
        siz[y] += siz[x];
        fa[x] = y;
        return;
    }
    int kruskal()
    {
        sort(e + 1,e + 1 + m);
        int tot = 0,ans = 0;    
        for(int i = 1;i <= m;i++)
        {
            int x = find(e[i].x),y = find(e[i].y);
            if(x != y)
            {
                merge(x,y);
                ans += e[i].val;
                tot++;
            }
            if(tot == n - 1) break;
        }
        return ans;
    }
    int c[N];
    using namespace std;
    int main()
    {
        scanf("%d %d",&n,&m);
        int minn = 1000000;
        for(int i = 1;i <= n;i++) 
        {
            scanf("%d",&c[i]);
            minn = min(c[i],minn);
            fa[i] = i;
            siz[i] = 1;
        }
        for(int i = 1;i <= m;i++) 
        {
            scanf("%d %d %d",&e[i].x,&e[i].y,&e[i].val);
            e[i].val = (e[i].val << 1) + c[e[i].x] + c[e[i].y];
        }
        printf("%d
    ",kruskal() + minn);
        return 0;
    }
  • 相关阅读:
    STP RSTP
    数组与文字处理
    3 算法、控制结构
    2 变量、运算符、位运算
    1
    小程序点击变换,
    小程序授权demo
    小程序获取参数
    小程序是否转发群还是个人(转发功能)
    小程序分享转发功能实现demo
  • 原文地址:https://www.cnblogs.com/lijilai-oi/p/10939755.html
Copyright © 2020-2023  润新知