1. 程式人生 > >hdu 2196 Computer 【樹形DP求直徑】

hdu 2196 Computer 【樹形DP求直徑】

題意:求每個點的最遠距離

思路:對於有向圖<u,v>   dp[u][0] 表示 u向子節點(向下)能到達的最圓距離
                                         dp[u][1] 表示 u向子節點能到達的此遠距離
                                         dp[u][2] 表示 u向父節點(向上)能到達的最遠距離

第一次 dfs 從下到上遍歷圖求出 dp[u][0]   dp[u][1],

第二次 dfs 從上到下遍歷圖求出 dp[u][2];

程式碼還有解釋

#include<stdio.h>
#include<string.h>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N=5e4+10;

struct node
{
    int v,ne,w;
}edge[N];
int head[N],isroot[N];
int dp[N][3];
int e,n;

void add(int a,int b,int c)
{
    edge[e].v=b;
    edge[e].w=c;
    edge[e].ne=head[a];
    head[a]=e++;
}

void dfs1(int u)
{
    for(int i=head[u];i!=-1;i=edge[i].ne)
    {
        int v=edge[i].v;
        dfs1(v);
        int temp=dp[v][0]+edge[i].w;
        if(temp>dp[u][0])
        {
            dp[u][1]=dp[u][0];
            dp[u][0]=temp;
        }
        else if(temp>dp[u][1])
            dp[u][1]=temp;
    }
}

void dfs2(int u)
{
    for(int i=head[u];i!=-1;i=edge[i].ne)
    {
        int v=edge[i].v;
        int w=edge[i].w;
        if(dp[u][0]==dp[v][0]+w)
            dp[v][2]=max(dp[u][2],dp[u][1])+w;
            //如果此時v就是u向下走的最長距離樹枝的節點,
            //那麼讓dp[u][2],dp[u][1]比較,因為要更新向上走的最遠距離;
            //向上走的最遠距離可能是u向上走的最遠距離也可能是從u到子節點的此遠距離(因為此時為u向下的最遠距離的樹枝)
        else
            dp[v][2]=max(dp[u][2],dp[u][0])+w;
            //否則用dp[u][2],dp[u][0]比較,更新v向上走的最遠距離
        dfs2(v);
    }
}

int main()
{
    while(~scanf("%d",&n))
    {
        int a,b,c;
        memset(head,-1,sizeof(head));
        memset(isroot,0,sizeof(isroot));
        e=0;
        for(int i=2;i<=n;i++)
        {
            scanf("%d %d",&b,&c);
            add(b,i,c);
        }
        memset(dp,0,sizeof(dp));
        dfs1(1);
        dfs2(1);
        for(int i=1;i<=n;i++)
            printf("%d\n",max(dp[i][2],dp[i][0]));
            //最後讓向上的最遠距離和向下的最遠距離比較
    }
    return 0;
}