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 Haskell (judge verdict: Accepted)

{-# OPTIONS_GHC -O2 #-}
{-# LANGUAGE FlexibleContexts #-}

import           Control.Applicative
import           Control.Monad
import           Control.Monad.Primitive
import           Control.Monad.ST
import qualified Data.ByteString.Char8       as B
import qualified Data.ByteString.Unsafe      as B
import           Data.Char
import           Data.Function
import qualified Data.Vector                 as V
import qualified Data.Vector.Generic         as G
import qualified Data.Vector.Generic.Mutable as GM
import qualified Data.Vector.Unboxed         as U

main :: IO ()
main = do
    n <- readLn
    edges <- U.unfoldrN (n-1) (readInt3.B.dropWhile isSpace) <$> B.getContents
    putStr . unlines . map show . solve $ undirectedGraph n edges

solve :: Graph -> [Cost]
solve gr = U.toList $ height gr

readInt3 :: B.ByteString -> Maybe ((Int,Int,Int), B.ByteString)
readInt3 bs = Just ((x,y,z),bsz)
  where
    Just (x, bsx) = B.readInt bs
    Just (y, bsy) = B.readInt $ B.unsafeTail bsx
    Just (z, bsz) = B.readInt $ B.unsafeTail bsy

unsafeIndex2 :: (G.Vector u a, G.Vector v (u a))
             => v (u a) -> Int -> Int -> a
unsafeIndex2 vv i j = G.unsafeIndex (G.unsafeIndex vv i) j
{-# INLINE unsafeIndex2 #-}

unsafeRead2 :: (PrimMonad m, GM.MVector mu a, G.Vector v (mu (PrimState m) a))
            => v (mu (PrimState m) a) -> Int -> Int -> m a
unsafeRead2 vv i j = GM.unsafeRead (G.unsafeIndex vv i) j
{-# INLINE unsafeRead2 #-}

unsafeWrite2 :: (PrimMonad m, GM.MVector mu a, G.Vector v (mu (PrimState m) a))
             => v (mu (PrimState m) a) -> Int -> Int -> a -> m ()
unsafeWrite2 vv i j x = GM.unsafeWrite (G.unsafeIndex vv i) j x
{-# INLINE unsafeWrite2 #-}

unsafeModify2 :: (PrimMonad m, GM.MVector mu a, G.Vector v (mu (PrimState m) a))
             => v (mu (PrimState m) a) -> Int -> Int -> (a -> a) -> m ()
unsafeModify2 vv i j f = unsafeRead2 vv i j >>= unsafeWrite2 vv i j . f
{-# INLINE unsafeModify2 #-}

iforM_ :: (Monad m, G.Vector v a, G.Vector v (Int, a))
       => v a -> (Int -> a -> m b) -> m ()
iforM_ vec =  G.forM_ (G.indexed vec) . uncurry
{-# INLINE iforM_ #-}

type Vertex = Int
type Cost = Int
type Edge = (Vertex, Vertex, Cost)
type Graph = V.Vector (U.Vector (Vertex, Cost))

directedGraph :: Int -> U.Vector Edge -> Graph
directedGraph numV edges = V.map U.fromList
    . V.unsafeAccumulate (flip (:)) (V.replicate numV [])
    . U.convert
    . U.map (\(src, dst, cost) -> (src, (dst, cost)))
    $ edges

undirectedGraph :: Int -> U.Vector Edge -> Graph
undirectedGraph numV edges = directedGraph numV
    $ edges U.++ U.map reverseEdge edges

vertices :: Graph -> U.Vector Vertex
vertices gr = U.generate (V.length gr) id

reverseEdge :: Edge -> Edge
reverseEdge (src, dst, cost) = (dst, src, cost)
{-# INLINE reverseEdge #-}

nothing :: Int
nothing = -1

height :: Graph -> U.Vector Cost
height tree = runST $ do
    mdp <- V.mapM U.thaw tree
    U.forM_ (vertices tree) $ \v ->
        iforM_ (V.unsafeIndex tree v) $ \i (u, _) ->
            unsafeWrite2 mdp v i (u, nothing)
    U.forM_ (vertices tree) $ \v ->
        iforM_ (V.unsafeIndex tree v) $ \i (u, _) -> do
            isVisited <- (/=nothing) . snd <$> unsafeRead2 mdp v i
            unless isVisited . void $
                fix `flip` v `flip` u `flip` i $ \visit src dst dstIx -> do
                    cost <- snd <$> unsafeRead2 mdp src dstIx
                    if cost /= nothing
                    then return cost
                    else do
                        unsafeWrite2 mdp src dstIx
                            $ unsafeIndex2 tree src dstIx
                        iforM_ (V.unsafeIndex tree dst) $ \j (w, _) ->
                            when (src /= w) $ do
                                let c = snd $ unsafeIndex2 tree src dstIx
                                new <- (+c) <$> visit dst w j
                                old <- snd <$> unsafeRead2 mdp src dstIx
                                when (old < new) $
                                    unsafeWrite2 mdp src dstIx (dst, new)
                        snd <$> unsafeRead2 mdp src dstIx

    dp <- V.mapM U.unsafeFreeze mdp
    return . U.generate (V.length tree)
        $ U.foldl' max 0 . U.map snd . V.unsafeIndex dp