Problem:
Height of a Tree

Given a tree T with non-negative weight, find the height of each node of the tree. For each node, the height is the distance to the most distant leaf from the node.

Input

n
s1 t1 w1
s2 t2 w2
:
sn-1 tn-1 wn-1

The first line consists of an integer n which represents the number of nodes in the tree. Every node has a unique ID from 0 to n-1 respectively.

In the following n-1 lines, edges of the tree are given.

si and ti represent end-points of the i-th edge (undirected) and wi represents the weight (distance) of the i-th edge.

Output

The output consists of n lines. Print the height of each node 0, 1, 2, ..., n-1 in order.

Constraints

1 ≤ n ≤ 10,000

0 ≤ wi ≤ 1,000

Sample Input 1

4
0 1 2
1 2 1
1 3 3

Sample Output 1

5
3
4
5

Solution in C# (judge verdict: Accepted)

using System;
using System.Linq;//リストの使用
using System.Collections.Generic;
using System.Text;//テキストの高速出力に必要
class Program
{
static int n = int.Parse(Console.ReadLine());
static List<int>[] nextVertexList = new List<int>[n];//隣接頂点リスト（リストの入った配列）
static List<long>[] nextDistanceList = new List<long>[n];//隣接頂点までの距離リスト
static int nex;
static long cost;
static long[] dis = new long[n];
static long[] answers = new long[n];

  static void Main()
  {
    for(int i = 0; i < n; i++)
    {
      nextVertexList[i] = new List<int>();
      nextDistanceList[i] = new List<long>();
    }
  
    for(int i = 0; i < n-1; i++)
    {
      string[] input = Console.ReadLine().Split(' ');
      int s = int.Parse(input[0]);
      int t = int.Parse(input[1]);
      long w = long.Parse(input[2]);
      nextVertexList[s].Add(t);
      nextDistanceList[s].Add(w);
      nextVertexList[t].Add(s);
      nextDistanceList[t].Add(w);
    }

    Dfs(0,-1);
    DfsSub(0,0,-1);
    for(int i = 0; i < n; i++) Console.WriteLine(answers[i]);
  }

  static void VertexSet(int vertexNum, int partnerNum)
  {
    nex = nextVertexList[vertexNum][partnerNum];
    cost = nextDistanceList[vertexNum][partnerNum];
  }

  static void Dfs(int x, int pre)
  {
    for(int i = 0; i < nextVertexList[x].Count(); i++)
    {
      VertexSet(x,i);
      if(nex == pre) continue;
      Dfs(nex,x);
      VertexSet(x,i);
      dis[x] = Math.Max(dis[x], dis[nex]+cost);
    }
  }

  static void DfsSub(int x, int dpre, int pre)
  {
    long[][] child = new long[nextVertexList[x].Count()+1][];
    for(int i = 0; i < nextVertexList[x].Count()+1; i++)
    {
      child[i] = new long[2];
    }
    child[0][0] = 0;
    child[0][1] = -1;

    for(int i = 0; i < nextVertexList[x].Count(); i++)
    {
      VertexSet(x,i);

      if(nex == pre) child[i+1][0] = dpre+cost;
      else child[i+1][0] = dis[nex]+cost;

      child[i+1][1] = nex;
    }
    var sorted = child.OrderByDescending(a => a[0]).ThenByDescending(a => a[1]).ToList();
    if(sorted.Count() > 1) answers[x] = Math.Max(sorted[0][0], sorted[1][0]);
    else answers[x] = sorted[0][0];

    for(int i = 0; i < nextVertexList[x].Count(); i++)
    {
      VertexSet(x,i);
      if(nex == pre) continue;
      DfsSub(nex, (int)sorted[(nex == sorted[0][1]?1:0)][0], x);
    }
    
  }
  
}