HDU - 2196 (tree dp)

Source title: the Click
asked the farthest node in the tree to tree in the path of another node.
Starting from a node analysis, tree dp is looking for his child node status between the parent node.
If you choose to go the current node child node can be found that he would not go parent, then he can only keep going and go all the child nodes. This can be the first to write a dfs1 () is represented, from the bottom.
If you choose to go the current node parent node, then you may choose to go after the parents the child node or parent node's parent node. With DFS2 () to indicate, from top to bottom.
Considering that the parent will still walk away a child node, first performed dfs1 ().
Specific visible code.

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<map>
#include<algorithm>
#include<queue>
#define MAX_len 50100*4
using namespace std;
typedef long long ll;
int n;
struct A{
    int v,w;
};
vector<A>hh[10011];
bool vis[10011];
int fa[10011];
int dp[10011][2];// 0表示走儿子结点    1表示走父亲节点
int dfs1(int root)//表示走的是儿子结点,一旦走了儿子结点的话就不可能再走父亲节点,是一直往下走的,所以dfs一直到看做1为根到叶子节点,从下往上做dp
{
    vis[root]=true;
    dp[root][0]=0;
    for(int i=0;i<hh[root].size();i++)
    {
        int v=hh[root][i].v;
        if(vis[v])
            continue;
        dp[root][0]=max(dp[root][0],dfs1(v)+hh[root][i].w);
    }
    return dp[root][0];
}
void dfs2(int root,int f)//如果走的是父亲结点,则有可能走父亲的其他子节点,从上往下的dp
{
    //vis[root]=true;
    int t=0;
    dp[root][1]=dp[f][1];
    for(int i=0;i<hh[f].size();i++)
    {
        int v=hh[f][i].v;
        if(v==fa[f])
            continue;
        if(v==root)
            t=hh[f][i].w;
        else
            dp[root][1]=max(dp[root][1],dp[v][0]+hh[f][i].w);
    }
    dp[root][1]+=t;
    for(int i=0;i<hh[root].size();i++)
        if(hh[root][i].v!=f)
         dfs2(hh[root][i].v,root);
}
int main()
{
    while(~scanf("%d",&n))
    {
        memset(dp,0,sizeof(dp));
        memset(vis,false,sizeof(vis));
        int i,j,k;
        for(i=1;i<=n;i++)
            hh[i].clear();
        for(i=2;i<=n;i++)
        {
            int v,w;
            scanf("%d %d",&v,&w);
            fa[i]=v;
            hh[v].push_back((A){i,w});
            hh[i].push_back((A){v,w});
        }
        dfs1(1);//就直接以1为根结点进行dp
        dfs2(1,0);
        for(i=1;i<=n;i++)
        printf("%d\n",max(dp[i][0],dp[i][1]));
    }
    return 0;
}

Published 72 original articles · won praise 19 · views 7502

Guess you like

Origin blog.csdn.net/weixin_43958964/article/details/104440493