hdu 2196

#include <iostream>
#include <cstring>
#include <stdio.h>

using namespace std;

const int MAXN = 100005;

int proot[MAXN];
int down_m[MAXN];
int down_s[MAXN];
int marked[MAXN];
int up[MAXN];
int vis[MAXN];

struct Node
{
    int to;
    int next;
    int w;
}node[MAXN];

int sum ;
int head[MAXN];

void addedge ( int a ,int b ,int w )
{
    int temp ;
    temp = head[a];
    head[a] = sum;
    node[sum].next = temp;
    node[sum].to = b;
    node[sum].w = w;
    sum ++;

    temp = head[b];
    head[b] = sum;
    node[sum].next = temp;
    node[sum].to = a;
    node[sum].w = w;
    sum ++;
}

int dfs1 ( int root )
{
    int m1 = -1;
    int m2 = -1;
    int id;
    int flag = 0 ;
    vis[root] = 1;
    //cout << root << endl;
    //getchar();
    int temp;
    for ( int i = head[root] ; i != -1 ; i = node[i].next )
    {
        int v = node[i].to;
        if ( !vis [v] )
        {
            flag = 1;
            int w = node[i].w;
            temp = dfs1 ( v );
            if ( m1 < ( temp + w )  )
            {
                m2 = m1;
                m1 = temp+w;
                id = v;
            }
            else if ( m1 == ( temp + w ) )
                m2 = m1;
            else if ( (temp + w)  > m2 )
                m2 = temp +w;
        }
    }
   if ( m2 == -1 )
         m2 = 0;
    if ( flag == 0 )
    {
        down_m[root] = 0;
        down_s[root] = 0;
    }
    else
    {
        down_m[root] = m1;
        marked[root] = id;
        down_s[root] = m2;
    }
    return down_m[root] ;
}

void dfs2 (  int root )
{
        vis[root] = 1;
       for ( int i = head[root] ; i != -1 ; i = node[i].next )
       {
            int v = node[i].to;
            if ( !vis[v] )
            {
                int w = node[i].w;
                if ( v == marked[root] )
                    up[v] = max ( down_s[root] , up [root] ) + w;
                else
                    up[v] = max ( down_m[root] , up[root] ) + w ;
                dfs2 ( v );
            }
       }
}

int GetInt(){  //据说这样能快
    char ch=getchar();
    while(ch< '0' || ch > '9' ) ch = getchar();
    int num = 0;
    while(ch >= '0' && ch <= '9'){
        num = num*10+ch-'0';
        ch = getchar();
    }
    return num;
}

int main()
{
    int n;
    int a, b;
    while ( scanf("%d" , &n )!= EOF )
    {
        sum = 0;
        memset ( down_m , 0 , sizeof ( down_m ));
        memset ( down_s, 0 , sizeof ( down_s ));
        memset ( up , 0 , sizeof ( up ));
        memset ( vis , 0 , sizeof ( vis ));
        memset ( marked , 0 , sizeof ( marked ));
        memset ( head,  -1 , sizeof ( head ));
        for ( int i = 2 ; i <= n ; i ++ )
        {
            a = GetInt ();
            b = GetInt();
            //cout << a << i << b << endl;
            addedge ( i , a , b  );
        }
        dfs1 ( 1 );
        memset ( vis , 0 , sizeof ( vis ));
        up[1] = 0;
        dfs2 ( 1 );
        for ( int i = 1 ; i <= n ; i ++ )
            printf("%d\n" , max( up[i] , down_m[i] ) );
    }
    return 0;

}

树状dp , 写的非常的乱

 

up 记录向上的最长路径 两个down 分别记录向下的最长和次长路径。

第一次dfs 从下到上 搜完向下最长和次长路径的。

第二次dfs从上到下搜索 找到从上来的最长的路径。 注意可能与最长路径相冲突 这个时候就需要记录最长路径的id 当取不了最长的 就取次长的。

最后 从向上和向下最长的 选一个大的就行了。


 



评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值