[HDU6662] Acesrc and Travel (tree Dp)

Topic Link

main idea

Tree is given, a weight value for each point \ (A [I] \) , there are two very smart man A and B.
Both A and B take turns walking together in the trees, not to go through before the point. (AB time together)
A upper hand, and may determine a starting point. A desired traveled, B wants weights and right of the minimum and maximum points.
The final weights and seek.

Thinking

First, there is a very clear idea of the tree Dp:
set \ (F0 [u] \) represented by \ (u \) within the sub-tree root, armor just get to \ (u \) weights as a starting point and .
Set \ (F1 [u] \) represented by \ (U \) within the subtree rooted, B upper hand to \ (U \) as a starting point and weights.
Then transfer the formula to is:
\ (F0 [U] = Min (Fl [V]) + A [U] \)
\ (Fl [U] = Max (F0 [V]) + A [U] \)
where \ (v \) to \ (u \) of a son.
So that we can deal with the answer to each point just go within the scope of its sub-tree.


From a certain point of consideration, walk up the answer form.

We set \ (TP [V] \) said they did not go \ (V \) subtree, armor just get to \ (V \) as a starting point and weights.
So \ (TP [V] \) update there will be two cases, one is to go \ (U \) , then go \ (U \) of a son.

In this case, definitely choose A \ (U \) son of (F0 \) \ maximum value, that \ (F1 [U] \) .
But due to the \ (V \) , where possible, in itself is the greatest, so it should be recorded (F1 \) \ the maximum value and the second largest value transferred.

For another, that is, go \ (U \) , walk \ (Fa \) situation.

For this case, go to \ (Fa \) when, \ (B \) will choose the smaller it while walking.
So that \ (Fa \) all sons smallest \ (F1 \) , namely \ (F0 [Fa] \) and \ (Fa \) cases go up \ (TP [Fa] \) whichever is less on the line a.
However Similarly, \ (the U-\) is the smallest possible, so the next record \ (F0 \) the minimum value and the second smallest value transferred.

For both (TP \) \ selected because it is the case of \ (A \) is selected, so that whichever is greater.
Note: the transfer \ (TP \) , the time to pay attention to the case of a chain.

Finally, at which point the enumeration as a starting point, take \ (F0 [U] [0 ] \) and \ (TP [U] \) of a smaller value on the line.

Note that leaf node to the root values.

Code

Details over more error-prone spot focused on the initial assignment and roots.

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXN=600005;
const long long INF=1e17;
int K,N,A[MAXN];
int son0[MAXN],son1[MAXN];
long long Ans;
long long F0[MAXN][2],F1[MAXN][2];//0:A|||||||1:B
long long TP[MAXN];
vector<int>P[MAXN];
void DFS(int u,int fa){
    int Ok=0;
    int size=P[u].size();
    for(int i=0;i<size;i++){
        int v=P[u][i];
        if(v==fa)continue;
        DFS(v,u);Ok=1;
        if(F1[v][0]+A[u]<F0[u][0])F0[u][1]=F0[u][0],F0[u][0]=min(F0[u][0],F1[v][0]+A[u]),son0[u]=v;
        else F0[u][1]=min(F0[u][1],F1[v][0]+A[u]);
        if(F0[v][0]+A[u]>F1[u][0])F1[u][1]=F1[u][0],F1[u][0]=max(F1[u][0],F0[v][0]+A[u]),son1[u]=v;
        else F1[u][1]=max(F1[u][1],F0[v][0]+A[u]);
    }
    if(!Ok)F0[u][0]=F0[u][1]=F1[u][0]=F1[u][1]=A[u];
}
void DFS2(int u,int fa){
    int size=P[u].size();
    for(int i=0;i<size;i++){
        int v=P[u][i];
        if(v==fa)continue;
        long long val1=INF,val2=INF;
        if(P[u].size()!=2){
            if(son1[u]==v)val1=F1[u][1];
            else val1=F1[u][0];
        }else val1=u==1?A[u]:-INF;
        if(P[fa].size()!=2){
            if(son0[fa]==u)val2=F0[fa][1];
            else val2=F0[fa][0];
        }val2=min(val2,TP[fa]);
        TP[v]=A[v]+max(val1,val2+A[u]);
        DFS2(v,u);
    }
}
int main(){
    //freopen("data.txt","r",stdin);
    //freopen("mine.txt","w",stdout);
    scanf("%d",&K);
    while(K--){
        scanf("%d",&N);
        for(int i=0;i<=N;i++){
            F0[i][0]=F0[i][1]=INF;
            F1[i][0]=F1[i][1]=-INF;
            son0[i]=son1[i]=0;TP[i]=-INF;
            P[i].clear();
        }
        for(int i=1;i<=N;i++)scanf("%d",&A[i]);
        for(int i=1,x;i<=N;i++)scanf("%d",&x),A[i]-=x;
        if(N==1){
            printf("%d\n",A[1]);
            continue;
        }
        for(int i=1,x,y;i<N;i++){
            scanf("%d%d",&x,&y);
            P[x].push_back(y);
            P[y].push_back(x);
        }Ans=-INF;P[1].push_back(0);
        DFS(1,0);
        if(P[1].size()!=2)TP[1]=INF;
        else TP[1]=A[1];
        DFS2(1,0);
        Ans=F0[1][0];
        for(int i=2;i<=N;i++){
            if(P[i].size()==1)Ans=max(Ans,TP[i]);
            else Ans=max(Ans,min(F0[i][0],TP[i]));
        }
        printf("%lld\n",Ans);
    }
}

Guess you like

Origin www.cnblogs.com/ftotl/p/11809273.html