#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;
#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 当取不了最长的 就取次长的。
最后 从向上和向下最长的 选一个大的就行了。