[ZJOI2007] Temporal synchronization tree DP

The meaning of problems: given an N unrooted trees of nodes, each edge has a weight V, select a point as a key, you can arbitrarily increased the weight of an edge, so that the request from the key points , a leaf node to any of the distances are the same and the need to increase the weight.

 

data range:

For . 4 0 % of the data, N ≤ 1000

For . 1 0 0 % of the data, N ≤ 500000, 1000000 ≤ V

 -------------------------------------split line----------- -------------------------

Solution: a relatively obvious tree DP, difficult to think we are on par with other chains to the longest chain.

Scanning the tree again, the process from the end of the current node number of edges upward num, and the current node to the leaf node and the distance sum.

Calculated from the leaf node farthest from the energizer maxn [x], then for the other leaf nodes, the need to increase the apparent length that is maxn [x] * num - sum.

The answer can be accumulated.

#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\n", f[root]);
}
int main(){
    init();
    work();
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/smilke/p/11576955.html