hdoj2196 (tree dp, the diameter of the tree)

Topic link: https: //vjudge.net/problem/HDU-2196

The meaning of problems: given a tree, each node seeking maximum distance that can be reached.

Ideas:

  If the tree is the longest distance is obtained, the two bfs on the line. But here all seek is the most distant point of the tree dp classic title, like an hour, or dp doing too little. Analysis available for any node u, its maximum distance is the longest distance extending either downwardly extending upwardly either the longest distance.

  We dp [u] [0] represents a node u downward (sub-node) of the longest distance, Pt [u] recording number of the first child node through the longest distance, such as through the longest distance u- > v, then pt [u] = v. dp [u] [1] records u downwardly second shortest distance, dp [u] [0], dp [u] [1] can be obtained by one dfs, the dfs information parent node obtained by the sub-node.

  dp [u] [2] Up recording node u (parent node) of the longest distance, u is assumed that the parent node is k, consider two cases:

    1.pt [k] = u (k downwardly through the longest path U): DP [U] [2] = W ku + max (DP [K] [. 1], DP [K] [2]), That parent node times to go a long distance, the distance is still up.

    2.pt [K] = U:! DP [U] [2] = W ku + max (DP [K] [0], DP [K] [2]), i.e., the longest distance to go parent node, or up distance.

  For each node, the result is max (dp [u] [0], dp [u] [2]).

AC Code:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

const int maxn=10005;
struct node{
    int v,w,nex;
}edge[maxn];
int n,dp[maxn][3],pt[maxn],head[maxn],cnt;

void adde(int u,int v,int w){
    edge[++cnt].v=v;
    edge[cnt].w=w;
    edge[cnt].nex=head[u];
    head[u]=cnt;
}

void dfs1(int u){
    dp[u][0]=dp[u][1]=pt[u]=0;
    for(int i=head[u];i;i=edge[i].nex){
        int v=edge[i].v,w=edge[i].w;
        dfs1(v);
        if(dp[v][0]+w>=dp[u][0]){
            pt[u]=v;
            dp[u][1]=dp[u][0];
            dp[u][0]=dp[v][0]+w;
        }
        else if(dp[v][0]+w>dp[u][1])
            dp[u][1]=dp[v][0]+w;
    }
}

void dfs2(int u){
    for(int i=head[u];i;i=edge[i].nex){
        int v=edge[i].v,w=edge[i].w;
        if(pt[u]==v) dp[v][2]=w+max(dp[u][1],dp[u][2]);
        else dp[v][2]=w+max(dp[u][0],dp[u][2]);
        dfs2(v);
    }
}

int main(){
    while(~scanf("%d",&n)){
        cnt=0;
        memset(head,0,sizeof(head));
        for(int i=2;i<=n;++i){
            int u,w;
            scanf("%d%d",&u,&w);
            adde(u,i,w);
        }
        dfs1(1);
        dfs2(1);
        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/FrankChen831X/p/11375572.html