hdu 2196

来源:互联网 发布:普拉达男鞋高仿淘宝店 编辑:程序博客网 时间:2024/05/01 22:04
#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 当取不了最长的 就取次长的。

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


 



原创粉丝点击