HDU 2196 Computer and second scanning transducer root DP

Meaning of the questions: Given a tree, the tree all point to seek from its farthest point.

Data range: 1 <= N <= 100000

------------------------------------------ I am dividing line ---- --------------------------------------

Max {a distance of the longest distance within its sub-tree, the parent node without passing through the longest distance in the sub-tree for each node u, u}, its possible to reach: explanations. So, we can pre-dfs first pass node x to the longest distance in its sub-tree, incidentally, seeking a next long distance, easy transfer.

// F [x] [0] represents the longest distance x to which the leaf node subtree, f [x] [1] indicates which subtree to x times long distance leaf node. 
void DFS1 ( int X, int FA) {
     for ( int I = head [X]; I; I = E [I] .next) {
         int Y = E [I] .to;
         IF (FA == Y) Continue ; 
        DFS1 (Y, X); 
        IF (F [Y] [ 0 ] + E [I] .v> F [X] [ 0 ]) { // update times the longest distance and long distance. 
            F [X] [ . 1 ] = F [X] [ 0 ]; 
            F [X] [ 0 ] = F [Y] [ 0 ] + E [I] .v; 
        }
        else f[x][1] = max(f[x][1], f[y][0] + e[i].v);
    }
}

In the second scan, consider the contribution of each point to change the root of the change.

Two cases: . ① longest path on the current node is not the parent node v ② current node v in the longest path of the parent node.

Clearly then state transition equation: ① d [y] = max (f [x] [0], d [x]) + e [i] .v; ② d [y] = max (f [x] [1] , d [x]) + e [i] .v;

The total time complexity of O (N).

void DFS2 ( int X, int FA) {
     for ( int I = head [X]; I; I = E [I] .next) {
         int Y = E [I] .to;
         IF (FA == Y) Continue ;
         IF (F [X] [ 0 ] == F [Y] [ 0 ] + E [I] .v) D [Y] = max (F [X] [ . 1 ], D [X]) + E [ I] .v; // Y longest distance in the x-path. 
        the else D [Y] = max (F [x] [ 0 ], D [x]) + E [I] .v; // Y x is not the longest distance path. 
        ANS [Y] = max (D [Y], F [Y] [ 0 ]);     
        DFS2 (Y, X); 
    } 
}

So, this question will be solved, accompanied by the complete code:

#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, head[N], cnt = 0, ans[N];
int f[N][2], d[N];
struct node{ int 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 the Add ( int X, int Y, int Z) { 
    E [ ++ CNT] .to = Y; E [CNT] .v = Z; 
    E [CNT] .next = head [X] ; head [x] = CNT; 
} 
// F [x] [0] represents the longest distance x to which the leaf node subtree, f [x] [1] represents the x times its leaf node subtree long distance. 
void DFS1 ( int X, int FA) {
     for ( int I = head [X]; I; I = E [I] .next) {
         int Y = E [I] .to;
         IF (FA == Y) Continue ; 
        DFS1 (Y, X); 
        IF(f[y][0] + e[i].v > f[x][0]){ //状态转移 
            f[x][1] = f[x][0]; 
            f[x][0] = f[y][0] + e[i].v;
        }
        else f[x][1] = max(f[x][1], f[y][0] + e[i].v);
    }
}
void dfs2(int x, int fa){
    for(int i = head[x]; i; i = e[i].next){
        int y = e[i].to;
        IF (FA == Y) Continue ;
         IF (F [X] [ 0 ] == F [Y] [ 0 ] + E [I] .v) D [Y] = max (F [X] [ . 1 ], D [x]) + E [I] .v; // Y longest distance in the x-path. 
        the else D [Y] = max (F [x] [ 0 ], D [x]) + E [I] .v; // Y x is not the longest distance path. 
        ANS [Y] = max (D [Y], F [Y] [ 0 ]);     
        DFS2 (Y, X); 
    } 
} 
void the init () { 
    n- = Read (); 
    REP (I, . 1 , N- . 1 ) {
         int YY = Read (), VV = Read ();
        add(i+1, yy, vv); add(yy, i+1, vv);
    }
    dfs1(1, 0); ans[1] = f[1][0];
    dfs2(1, 0);
    rep(i, 1, n) printf("%d\n", ans[i]);
}
int main(){
    init();
    return 0;
}
View Code

 

Guess you like

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