Problem:
Diameter of a Tree

Given a tree T with non-negative weight, find the diameter of the tree.

The diameter of a tree is the maximum distance between two nodes in a tree.

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

Print the diameter of the tree in a line.

Constraints

1 ≤ n ≤ 100,000

0 ≤ wi ≤ 1,000

Sample Input 1

4
0 1 2
1 2 1
1 3 3

Sample Output 1

5

Sample Input 2

4
0 1 1
1 2 2
2 3 4

Sample Output 2

7

Solution in Rust (judge verdict: Accepted)

#[derive(Clone, Copy, Debug)]
struct Edge {
    to: usize,
    cost: usize,
}

fn diameter(adjl: &Vec<Vec<Edge>>, v: usize, p: usize, ans: &mut usize) -> usize {
    let mut sub_diam = std::collections::BinaryHeap::new();
    for e in &adjl[v] {
        if e.to == p {
            continue;
        } else {
            sub_diam.push(diameter(&adjl, e.to, v, ans) + e.cost);
        }
    }
    match sub_diam.len() {
        0 => 0,
        1 => {
            let m = sub_diam.pop().expect("something wrong");
            *ans = max(*ans, m);
            m
        }
        _ => {
            let m1 = sub_diam.pop().expect("something wrong");
            let m2 = sub_diam.pop().expect("something wrong");
            *ans = max(*ans, m1 + m2);
            m1
        }
    }
}

fn main() {
    let n = read();
    let mut adjl = vec![vec![]; n];
    for _ in 1..n {
        let (s, t, w): (usize, usize, usize) = (read::<usize>(), read::<usize>(), read::<usize>());
        adjl[s].push(Edge { to: t, cost: w });
        adjl[t].push(Edge { to: s, cost: w });
    }
    let mut ans = 0;
    diameter(&adjl, 0, 0, &mut ans);
    println!("{}", ans);
}

// =========
#[allow(unused_imports)]
use std::cmp::{max, min};
#[allow(unused_imports)]
use std::collections::{HashMap, HashSet};
#[allow(unused_imports)]
use std::process::exit;

#[allow(dead_code)]
const MOD: usize = 1000000007;

fn read<T: std::str::FromStr>() -> T {
    use std::io::Read;
    let stdin = std::io::stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

// =========