zoukankan      html  css  js  c++  java
  • bzoj1232 [Usaco2008Nov]安慰奶牛cheer

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1232

    【题解】

    这种删边的题一般都是最小生成树,考虑边权,因为要往返,所以边权是原来边权*2+两端点权。

    这样起点会少算一次。我们求出最小生成树后找一个点权最小的当起点就行了。。

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 5e5 + 10;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    
    int n, m, w[M], id[M], D;
    
    struct pa {
        int u, v, w;
        pa() {}
        pa(int u, int v, int w) : u(u), v(v), w(w) {}
        friend bool operator < (pa a, pa b) {
            return a.w<b.w;
        }
    }e[M];
    
    int fa[M];
    inline int getf(int x) {
        return fa[x] == x ? x : fa[x] = getf(fa[x]);
    }
    
    int main() {
        cin >> n >> m; D = m-n+1;
        for (int i=1; i<=n; ++i) fa[i] = i, scanf("%d", w+i);
        for (int i=1, u, v, _w; i<=m; ++i) {
            scanf("%d%d%d", &u, &v, &_w);
            e[i] = pa(u, v, 2*_w + w[u] + w[v]);
        }
        sort(e+1, e+m+1);
        ll ans = 0;
        int cnt = 0;
        for (int i=1; i<=m; ++i) {
            int fu = getf(e[i].u), fv = getf(e[i].v);
            if(fu == fv) continue;
            fa[fu] = fv;
            ans += e[i].w;
            ++cnt;
            if(cnt == n-1) break;
        }
        int mi = 1e9;
        for (int i=1; i<=n; ++i) mi = min(mi, w[i]);
        ans += mi;
        cout << ans;
        return 0;
    }
    View Code
  • 相关阅读:
    java回顾之多线程
    java回顾之异常
    模拟斗地主和冒泡排序
    java回顾之Map
    java回顾之集合List
    java回顾之树
    java回顾之单列集合、泛型、数据结构
    java回顾之类API再体验之引用类型小结
    java回顾之API初体验
    函数之 闭包函数 和 装饰器
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj1232.html
Copyright © 2011-2022 走看看