【树形DP】 HDU 2196 Computer

来源:互联网 发布:office2016 for mac卡 编辑:程序博客网 时间:2024/05/17 00:01

题目链接:  HDU 2196 Computer

分析:   先从任意一点开始, 求出它到其它点的最大距离, 然后以该点为中心更新它的邻点,

           再用被更新的点去更新邻点......依此递推 !

代码:

#include <iostream>#include <cstdio>#include <cmath>#include <cstdlib>#include <string>#include <cstring>#include <algorithm>#include <iomanip>using namespace std;const int inf = 0x7FFFFFFF;const int maxn = 11111;struct node{    int to, dix, sum;    node *next;}tree[maxn<<1], *head[maxn];int ptr, n; bool vis[maxn];int dp[maxn],h[maxn];void Init(){    ptr=1;    memset(dp,0,sizeof(dp));    memset(vis,false,sizeof(vis));    memset(head,0,sizeof(head));}void AddEdge(int x,int y,int s){    tree[ptr].dix=s;    tree[ptr].to=y;    tree[ptr].next=head[x];    head[x]=&tree[ptr++];}void DFS(int cnt){      vis[cnt]=true;    node *p=head[cnt];    while(p!=NULL){        if(vis[p->to]) {            p=p->next; continue;        }        DFS(p->to);        dp[cnt]=max(dp[cnt],dp[p->to]+p->dix);        p->sum=dp[p->to]+p->dix;        p=p->next;    }}void Tree_Dp(int father, int son){    if(vis[son]) return ;    vis[son]=true;    int Max=0;    node* p=head[father];    while(p!=NULL){        if(p->to!=son)             Max=max(Max,p->sum);        p=p->next;    }    p=head[son];    while(p!=NULL){        if(p->to==father){            p->sum=p->dix+Max;  break;        }        p=p->next;    }    p=head[son];    while(p!=NULL){        dp[son]=max(dp[son],p->sum);        Tree_Dp(son,p->to);        p=p->next;    }}int main(){    while(~scanf("%d",&n)&&n){        Init();        for(int i=2;i<=n;++i){            int a,b;  scanf("%d%d",&a,&b);            AddEdge(a,i,b);            AddEdge(i,a,b);        }                DFS(1);          ///得到1点到其它所有点的距离                memset(vis,false,sizeof(vis));        node* p=head[1];        while(p!=NULL){  ///从1的邻点开始更新            Tree_Dp(1,p->to);            p=p->next;        }        for(int i=1;i<=n;++i)            printf("%d\n",dp[i]);    }    return 0;}


原创粉丝点击