zoukankan      html  css  js  c++  java
  • [USACO08NOV]安慰奶牛Cheering up the Cow BZOJ 1232 Kruskal

    Farmer John变得非常懒, 他不想再继续维护供奶牛之间供通行的道路. 道路被用来连接N (5 <= N <= 10,000)个牧场, 牧场被连续地编号为1..N. 每一个牧场都是一个奶牛的家. FJ计划除去P(N-1 <= P <= 100,000)条道路中尽可能多的道路, 但是还要保持牧场之间的连通性. 你首先要决定那些道路是需要保留的N-1条道路. 第j条双向道路连接了牧场S_j和E_j (1 <= S_j <= N; 1 <= E_j <= N; S_j != E_j), 而且走完它需要L_j (0 <= L_j <= 1,000)的时间. 没有两个牧场是被一条以上的道路所连接. 奶牛们非常伤心, 因为她们的交通系统被削减了. 你需要到每一个奶牛的住处去安慰她们. 每次你到达第i个牧场的时候(即使你已经到过), 你必须花去C_i (1 <= C_i <= 1,000)的时间和奶牛交谈. 你每个晚上都会在同一个牧场(这是供你选择的)过夜, 直到奶牛们都从悲伤中缓过神来. 在早上起来和晚上回去睡觉的时候, 你都需要和在你睡觉的牧场的奶牛交谈一次. 这样你才能完成你的交谈任务. 假设Farmer John采纳了你的建议, 请计算出使所有奶牛都被安慰的最少时间. 对于你前10次的提交, 你的程序会在一部分正式的测试数据上运行, 并且返回运行的结果.

    Sample Output176 Hint


    Input

    * 第 1 行: 用空格隔开的两个整数N和P * 第 2..N+1 行: 第i+1行包含了一个整数: C_i * 第 N+2..N+P+1 行: 第 N+j+1 行包含用空格隔开的三个整数: S_j, E_j 和 L_j

    Output

    第 1 行: 一个整数, 所需要的总时间(包含和在你所在的牧场的奶牛的两次谈话时间).

    Sample Input5 7 10 10 20 6 30 1 2 5 2 3 5 2 4 12 3 4 17 2 5 15 3 5 6 4 5 12
     
    感觉自己语文太差,题目刚开始没怎么读懂.........
    本来就想着将点权合并到边上去,但还是害怕读错题目.....
    其实就是一个 kruskal 的题目;
    我们将点权以及边权*2的和算为该边的新权值,然后跑一边 Kruskal即可;最后加上权值最小的点即可;
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<map>
    #include<set>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<ctime>
    #include<deque>
    #include<stack>
    #include<functional>
    #include<sstream>
    //#include<cctype>
    //#pragma GCC optimize("O3")
    using namespace std;
    #define maxn 200005
    #define inf 0x3f3f3f3f
    #define INF 9999999999
    #define rdint(x) scanf("%d",&x)
    #define rdllt(x) scanf("%lld",&x)
    #define rdult(x) scanf("%lu",&x)
    #define rdlf(x) scanf("%lf",&x)
    #define rdstr(x) scanf("%s",x)
    typedef long long  ll;
    typedef unsigned long long ull;
    typedef unsigned int U;
    #define ms(x) memset((x),0,sizeof(x))
    const long long int mod = 1e9 + 7;
    #define Mod 1000000000
    #define sq(x) (x)*(x)
    #define eps 1e-3
    typedef pair<int, int> pii;
    #define pi acos(-1.0)
    const int N = 1005;
    #define REP(i,n) for(int i=0;i<(n);i++)
    typedef pair<int, int> pii;
    inline ll rd() {
        ll x = 0;
        char c = getchar();
        bool f = false;
        while (!isdigit(c)) {
            if (c == '-') f = true;
            c = getchar();
        }
        while (isdigit(c)) {
            x = (x << 1) + (x << 3) + (c ^ 48);
            c = getchar();
        }
        return f ? -x : x;
    }
    
    ll gcd(ll a, ll b) {
        return b == 0 ? a : gcd(b, a%b);
    }
    ll sqr(ll x) { return x * x; }
    
    /*ll ans;
    ll exgcd(ll a, ll b, ll &x, ll &y) {
        if (!b) {
            x = 1; y = 0; return a;
        }
        ans = exgcd(b, a%b, x, y);
        ll t = x; x = y; y = t - a / b * y;
        return ans;
    }
    */
    
    
    
    ll qpow(ll a, ll b, ll c) {
        ll ans = 1;
        a = a % c;
        while (b) {
            if (b % 2)ans = ans * a%c;
            b /= 2; a = a * a%c;
        }
        return ans;
    }
    
    int n, m;
    struct node {
        int u, v, w;
    }edge[maxn];
    
    int valnode[maxn];
    
    bool cmp(node a, node b) {
        return a.w < b.w;
    }
    int tot;
    int fa[maxn];
    int findfa(int x) {
        if (x == fa[x])return x;
        return fa[x] = findfa(fa[x]);
    }
    
    int kruskal() {
        int ans = 0;
        for (int i = 0; i <= n; i++)fa[i] = i;
        sort(edge , edge + tot, cmp);
        int cnt = 0;
        for (int i = 0; i < tot; i++) {
            int u = edge[i].u; int v = edge[i].v;
            int w = edge[i].w;
            if (findfa(u) != findfa(v)) {
                fa[findfa(u)] = findfa(v);
                ans += w; cnt++;
                if (cnt == n - 1)break;
            }
        }
        return ans;
    }
    
    void addedge(int u, int v, int w) {
        edge[tot].u = u; edge[tot].v = v; edge[tot++].w = w * 2 + valnode[u] + valnode[v];
    }
    int main()
    {
        //ios::sync_with_stdio(0);
        rdint(n); rdint(m); int minn = inf;
        for (int i = 1; i <= n; i++)rdint(valnode[i]), minn = min(minn, valnode[i]);
        for (int i = 1; i <= m; i++) {
            int u, v, w; rdint(u); rdint(v); rdint(w);
            addedge(u, v, w); addedge(v, u, w);
        }
        cout << kruskal()+minn << endl;
        return 0;
    }
    
    EPFL - Fighting
  • 相关阅读:
    redis 基本类型命令
    吴寿仁 学术
    吴寿仁:上海科技成果转化40年
    从“四技”服务的收益中提取奖酬金是否不受当年本单位工资总额限制、不纳入本单位工资
    高校科技成果转化为什么就这样的难
    高校成果转换
    中华人民共和国 促进科技成果转化法
    上海市促进科技成果转化条例
    项目管理
    欧几里得方法计算最大公约数Python版本
  • 原文地址:https://www.cnblogs.com/zxyqzy/p/9981375.html
Copyright © 2011-2022 走看看