zoukankan      html  css  js  c++  java
  • HDU 2196 树形DP Computer

    题目链接:  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
    ",dp[i]);
        }
        return 0;
    }
    


  • 相关阅读:
    继承
    面向对象
    数据库的数据操作
    数据库数据类型以及建库语句
    第一天
    继承与多态
    C#面向对象——对象成员、方法重载、引用类库等
    C#面向对象初步
    SQL2008知识回顾
    C#知识回顾
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3233741.html
Copyright © 2011-2022 走看看