Tree DP - HDU2196

Topic Link

Title meaning

Find out the length of each computer farthest computer

Topic analysis

For a node v, if the longest length in its sub-tree, we take dp [u] [0]

Otherwise, the maximum length to pass through its parent node u, v is the maximum length of the longest length = dis (u, v) + u of

The first case, if the length of the longest elapsed u v child node, then obviously undesirable longest length, then we would go to the length of the second long dp [u] [1]

The second case, if the length of the longest without u v child node, then take a longest length u dp [u] [0]

So each node, requires subtrees longest distance dp [u] [0], the second long-distance dp [u] [1]

For convenience of calculation, but also required the longest distance dp after a parent node [u] [2]

A more detailed look at this process may blogger blog

Topic Code

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
const int maxn=1e4+7;
int n,q,a,b,c,tot;
int head[maxn],dp[maxn][3],longest[maxn];
struct node{
    int to,w,next;
}edge[maxn*2];
void add(int u,int v,int w){
    edge[tot].to=v;
    edge[tot].w=w;
    edge[tot].next=head[u];
    head[u]=tot++;
}
int dfs1(int u,int fa){
    if(dp[u][0]>=0)return dp[u][0];
    dp[u][0]=dp[u][1]=dp[u][2]=longest[u]=0;
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        if(v==fa)continue;
        if(dp[u][0]<dfs1(v,u)+edge[i].w){
            dp[u][1]=dp[u][0];
            dp[u][0]=dfs1(v,u)+edge[i].w;
            longest[u]=v;
        }
        else if(dp[u][1]<dfs1(v,u)+edge[i].w){
            dp[u][1]=dfs1(v,u)+edge[i].w;
        }
    }
    return dp[u][0];
}
void dfs2(int u,int fa){
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        if(v==fa)continue;
        if(v==longest[u])dp[v][2]=max(dp[u][1],dp[u][2])+edge[i].w;
        else dp[v][2]=max(dp[u][0],dp[u][2])+edge[i].w;
        dfs2(v,u);
    }
}
int main(){
    while(~scanf("%d",&n)){
        tot=0;
        memset(head,-1,sizeof(head));
        memset(dp,-1,sizeof(dp));
        memset(longest,-1,sizeof(longest));
        for(int i=2;i<=n;i++){
            scanf("%d%d",&a,&b);
            add(a,i,b)/*,add(i,a,b)*/;
        }
        dfs1(1,0);
        dfs2(1,0);
        for(int i=1;i<=n;i++)
            printf("%d\n",max(dp[i][0],dp[i][2]));
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/helman/p/11273176.html