HDU 2196 Computer (树形DP)

来源:互联网 发布:vb猜数游戏程序 编辑:程序博客网 时间:2024/05/17 01:15

两次DFS,先从下往上搜一次,记录每个点到子树的最长距离与次长距离。次长距离的目的是如果在第二次更新的时候,最长距离与该子节点的方向是同一个方向,那就不能用这个最长距离了,只能用次长距离来更新。那么第二次dfs就是来从上往下来更新状态的。

代码如下:

#include <iostream>#include <string.h>#include <math.h>#include <queue>#include <algorithm>#include <stdlib.h>#include <map>#include <set>#include <stdio.h>using namespace std;#define LL __int64#define pi acos(-1.0)const int mod=100000000;const int INF=0x3f3f3f3f;const double eqs=1e-8;int head[11000], cnt, dp[11000][3], id[11000][3];struct node {        int u, v, w, next;} edge[30000];void add(int u, int v, int w){        edge[cnt].v=v;        edge[cnt].w=w;        edge[cnt].next=head[u];        head[u]=cnt++;}void dfs1(int u, int fa){        int i;        for(i=head[u]; i+1; i=edge[i].next) {                int v=edge[i].v;                if(v==fa) continue ;                dfs1(v,u);                if(dp[u][1]<dp[v][0]+edge[i].w) {                        dp[u][1]=dp[v][0]+edge[i].w;                        id[u][1]=v;                        if(dp[u][1]>dp[u][0]) {                                swap(dp[u][0],dp[u][1]);                                swap(id[u][1],id[u][0]);                        }                }        }}void dfs2(int u, int fa){        int i, tmp;        for(i=head[u]; i+1; i=edge[i].next) {                int v=edge[i].v;                if(v==fa) continue ;                if(id[u][0]==v)                        tmp=dp[u][1];                else tmp=dp[u][0];                if(dp[v][1]<edge[i].w+tmp) {                        dp[v][1]=edge[i].w+tmp;                        id[v][1]=u;                        if(dp[v][1]>dp[v][0]) {                                swap(dp[v][1],dp[v][0]);                                swap(id[v][1],id[v][0]);                        }                }                dfs2(v,u);        }}void init(){        memset(head,-1,sizeof(head));        cnt=0;}int main(){        int n, i, u, v, w;        while(scanf("%d",&n)!=EOF) {                init();                for(i=2; i<=n; i++) {                        scanf("%d%d",&v,&w);                        add(i,v,w);                        add(v,i,w);                }                memset(dp,0,sizeof(dp));                dfs1(1,0);                dfs2(1,0);                for(i=1; i<=n; i++) {                        printf("%d\n",dp[i][0]);                }        }        return 0;}


1 0