HDU 6662 Acesrc and Travel (换根dp)

Problem Description
Acesrc is a famous tourist at Nanjing University second to none. During this summer holiday, he, along with Zhang and Liu, is going to travel to Hong Kong. There are  n spots in Hong Kong, and n1 bidirectional sightseeing bus routes connecting these spots. They decide to visit some spots by bus.

However, Zhang and Liu have different preferences for these spots. They respectively set a satisfactory value for each spot. If they visit the ith spot, Zhang will obtain satisfactory value ai, and Liu will obtain bi. Starting with Zhang, they alternately decide the next spot to visit for the sake of fairness. There must be a bus route between the current spot and the next spot to visit. Moreover, they would never like to visit a spot twice. If anyone can't find such a next spot to visit, they have no choice but to end this travel.

Zhang and Liu are both super smart competitive programmers. Either want to maximize the difference between his total satisfactory value and the other's. Now Acesrc wonders, if they both choose optimally, what is the difference between total satisfactory values of Zhang and Liu?
 

 

Input
The first line of input consists of a single integer  T (1T30), denoting the number of test cases.

For each test case, the first line contains a single integer n (1n105), denoting the number of spots. Each of the next two lines contains n integers, a1,a2,,anand b1,b2,,bn (0ai,bi109), denoting the 
satisfactory value of Zhang and Liu for every spot, respectively. Each of the last n1 lines contains two integers x,y (1x,yn,xy), denoting a bus route between the xth spot and the yth spot. It is reachable from any spot to any other spot through these bus routes.

It is guaranteed that the sum of n does not exceed 5.01×105.
 

 

Output
For each test case, print a single integer in one line, the difference of total satisfactory values if they both choose optimally.
 

 

Sample Input
1 3 1 1 1 0 2 3 1 2 1 3
 

 

Sample Output
-1
 
Meaning of the questions:
Given a tree, corresponding to the two weights on each node are the satisfaction of two people, two of them want to make their degree of satisfaction subtract another person's satisfaction and as large as possible, seek final the resulting value.
Note that, the two men alternately selected direction, and can not go back, starting from the first personal choice.
(Meaning of the questions are too complicated, to put bad please forgive me)
Ideas:
DP tree, when the node 1 as the starting point to determine, for each selected point and the second largest value from the maximum value obtained by the first individual and the second individual.
Then change to the root.
There are many areas that need attention, such as if a point had only one son node or leaf node itself is, it needs special treatment, because the way in changing the root, cut off its relationship with the father node after its maximum and minimum value may be a problem.
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>

#define fuck(x) cerr<<#x<<" = "<<x<<endl;
#define debug(a, x) cerr<<#a<<"["<<x<<"] = "<<a[x]<<endl;
#define lson l,mid,ls
#define rson mid+1,r,rs
#define ls (rt<<1)
#define rs ((rt<<1)|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int loveisblue = 486;
const int maxn = 100086;
const int maxm = 200086;
const ll Inf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000000007;
const double eps = 1e-6;
const double pi = acos(-1);

intHead [MAXN], CNT;
 struct Edge {
     int the Next, V; 
} E [MAXM]; 

void add_edge member ( int U, int V) { 
    E [CNT] .NEXT = Head [U]; 
    E [CNT] .v = V; 
    Head [U] = CNT ++ ; 
} 

LL A [MAXN]; 

LL DP1 [ 2 ] [MAXN]; // 0 individuals selected from a first, a second selection from 
LL DP2 is [ 2 ] [ MAXN]; // Ci 
BOOL VIS [MAXN]; 

void DFS ( int U, int FA) {
     BOOL In Flag = to true;
     For ( int K = Head [U];! K = - . 1 ; K = E [K] .NEXT) {
         IF (E [K] .v == FA) {
             Continue ; 
        } 
        DFS (E [K]. V, U); 
        In Flag = to false ; 

        LL TMP1 = DP1 [ . 1 ] [E [K] .v]; 
        LL TMP0 = DP1 [ 0 ] [E [K] .v]; 

        // current by the first individual selection come, it must choose from the next by a second individual 
        IF (TMP1 <DP2 is [ 0 ] [U]) {the swap (TMP1, DP2 is [ 0 ] [U]);}
         IF (DP2 is [ 0 ] [U ] <DP1 [ 0][u]) { swap(dp2[0][u], dp1[0][u]); }

        if (tmp0 > dp2[1][u]) { swap(tmp0, dp2[1][u]); }
        if (dp2[1][u] > dp1[1][u]) { swap(dp2[1][u], dp1[1][u]); }
    }

    vis[u] = flag;
    //叶子节点的特殊处理
    if (flag) {
        dp1[0][u] = 0;
        dp1[1][u] = 0;
    }
    if (dp1[0][u] != Inf) dp1[0 ] [U] + = A [U];
     IF (DP1 [ . 1 !] [U] = -Inf) DP1 [ . 1 ] [U] + = A [U];
     IF (DP2 is [ 0 ] [U]! Inf =) DP2 is [ 0 ] [U] + = A [U];
     IF (DP2 is [ . 1 !] [U] = -Inf) DP2 is [ . 1 ] [U] + = A [U]; 
} 

LL ANS = - INF; 

void DFS1 ( int u, int FA) { 

    LL TMP0 = DP1 [ 0 ] [FA]; 
    LL TMP1 = DP1 [ . 1 ] [FA]; 


    // If the maximum value is transferred from the parent node to u, then It must take advantage of changing times the value of the root
    IF (DP1 TMP0 == [ . 1 ] [U] + A [FA]) { 
        TMP0 = DP2 is [ 0 ] [FA]; 
    } 
    IF (DP1 TMP1 == [ 0 ] [U] + A [FA]) { 
        TMP1 DP2 is = [ . 1 ] [fa]; 
    } 

    // If this fa u is only a son, and when 1 fa ==, this occurs before 
    IF (TMP1 == - Inf) { 
        TMP1 = a [fa]; 
    } 
    IF (TMP0 == Inf) { 
        TMP0 = A [FA]; 
    } 
    TMP0 + = A [U]; 
    TMP1 + = A [U]; 


    //u is a leaf node, sentence directly Laid 
    IF (VIS [u]) { 
        ANS = max (ANS, TMP1); 
    } 
    // This code and dfs in exactly the same 
    IF (TMP1 <DP2 is [ 0 ] [u]) { the swap (TMP1, DP2 is [ 0 ] [U]);}
     IF (DP2 is [ 0 ] [U] <DP1 [ 0 ] [U]) {the swap (DP2 is [ 0 ] [U], DP1 [ 0 ] [U] );} 

    IF (TMP0> DP2 is [ . 1 ] [U]) {the swap (TMP0, DP2 is [ . 1 ] [U]);}
     IF (DP2 is [ . 1 ] [U]> DP1 [ . 1 ] [U]) {the swap (DP2 is [ . 1 ] [U], DP1 [ . 1 ] [U]);} 

    ANS= max(ans, dp1[0][u]);

    for (int k = Head[u]; k != -1; k = e[k].Next) {
        if (e[k].v != fa)dfs1(e[k].v, u);
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    int T;
    scanf("%d", &T);
    while (T--) {
        int n;
        ans = -Inf;
        cnt = 0;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            Head[i] = -1;
            scanf("%lld", &a[i]);
            dp1[0][i] = dp2[0][i] = Inf;
            dp1[1][i] = dp2[1][i] = -Inf;

        }
        for (int i = 1; i <= n; i++) {
            ll x;
            scanf("%lld", &x);
            a[i] -= x;
        }
        for (int i = 1; i < n; i++) {
            int x, y;
            scanf("%d%d", &x, &y);
            add_edge(x, y);
            add_edge(y, x);
        }
        dfs(1, 0);
        ans = dp1[0][1];
        for (int k = Head[1]; k != -1; k = e[k].Next) {
            dfs1(e[k].v, 1);
        }
        printf("%lld\n", ans);
    }
    return 0;
}
View Code

The code in question can leave a message

Guess you like

Origin www.cnblogs.com/ZGQblogs/p/11355640.html