HDU - 2196(木DP)

元のタイトル:クリックして
他のノードのパスに木にツリー内の最も遠いノードを尋ねました。
ノードの分析から始めて、ツリーのDPは、親ノードとの間に彼の子ノードのステータスを探しています。
あなたは現在のノードの子ノードは、彼が親に行かないことを見つけることができます行くことを選択した場合は、その後、彼は唯一続けると、すべての子ノードを行くことができます。これは、下から、()で表されるDFS1を書くことができます。
あなたは現在のノードの親ノードを行くことを選択した場合は、親の子ノードまたは親ノードの親ノードの後に行くことを選択することができます。DFS2()で上から下に、指示します。
親はまだ、最初に行わDFS1を子ノードを離れて歩いていくことを考えると()。
特定の可視コード。

#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;
}

公開された72元の記事 ウォン称賛19 ビュー7502

おすすめ

転載: blog.csdn.net/weixin_43958964/article/details/104440493