• [ZJOI2007]时态同步 树形DP


    题意:给定一棵N个节点的无根树,每条边都有一个权值V,选取其中一个点作为关键点,你可以任意增加某条边的权值,求使得从关键点出发,到任意一个叶子节点的距离都相同所需要增加的权值和。

    数据范围:

    对于40%的数据,N ≤ 1000

    对于100%的数据,N ≤ 500000,V ≤ 1000000

     -------------------------------------分割线------------------------------------

    题解:一道比较显然的树形DP,不难想到我们把其他的链都向最长链看齐。

    扫描一遍树,自底向上处理出当前节点的出边数量num,以及当前节点到叶节点的距离和sum。

    算出最远的距离激发器的叶子节点距离maxn[x],然后对于其他叶子节点,所需要增加的长度显然即为 maxn[x] * num - sum。

    累加答案即可。

    #include<bits/stdc++.h>
    
    #define ll long long
    #define mp make_pair
    #define rep(i, a, b) for(int i = (a); i <= (b); i++)
    #define per(i, a, b) for(int i = (a); i >= (b); i--)
    
    using namespace std;
    
    typedef pair<int, int> pii;
    typedef double db;
    const int N = 1e6 + 50;
    int n, a[N], root; 
    int head[N], cnt = 0;
    ll maxn[N], f[N];
    struct node{ ll to, next, v; } e[N];
    inline int read(){
        int x = 0, f = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar();}
        while(ch >='0' && ch <='9') { x = (x<<3)+(x<<1)+(ch^48); ch = getchar();}
        return x*f;
    }
    void add(int x, int y, int z){
        e[++cnt].to = y; e[cnt].v = z;
        e[cnt].next = head[x]; head[x] = cnt;
    }
    void init(){
        n = read(); root = read();
        rep(i, 1, n-1) {
            int xx, yy, zz;
            xx = read(); yy = read(); zz = read();
            add(xx, yy, zz);
            add(yy, xx, zz);
        }  
    }
    void dfs(int x, int fa){
        f[x] = 0, maxn[x] = 0;
        ll sum = 0, num = 0;
        for(int i = head[x]; i; i = e[i].next){
            int y = e[i].to;
            if(y == fa) continue;
            dfs(y, x); num ++;
            f[x] += f[y];
            maxn[x] = max(maxn[y] + e[i].v, maxn[x]);
            sum += (ll)maxn[y] + e[i].v; 
        }
        f[x] += (ll)maxn[x] * num - sum;
    }
    void work(){
        dfs(root, 0);
        printf("%lld
    ", f[root]);
    }
    int main(){
        init();
        work();
        return 0;
    }
    View Code
  • 相关阅读:
    解决ERROR C2011: 'FD_SET' : 'STRUCT' TYPE REDEFINITION问题
    github简单使用教程
    Win32 多线程的创建方法和基本使用
    day 05
    day04
    day03
    day02
    day 06
    day_05
    day 05
  • 原文地址:https://www.cnblogs.com/smilke/p/11576955.html
Copyright © 2020-2023  润新知