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 C++14 (judge verdict: Accepted)

#include <bits/stdc++.h>

using namespace std;

template <class T>
struct edge {
    size_t to;
    T cost;
    edge(size_t to, T cost = 1) : to(to), cost(cost) {}
};

template <class T>
class graph {
private:
    const size_t count_nodes;
    const bool is_directed;
public:
    vector<edge<T>> *edges;
    graph(size_t count_nodes, bool is_directed = true) : count_nodes(count_nodes), is_directed(is_directed) {
        edges = new vector<edge<T>>[count_nodes];
    }
    ~graph() {
        delete [] edges;
    }
    size_t size() const { return count_nodes; }
    void make_edge(size_t u, size_t v, T cost) {
        edges[u].push_back(edge<T>(v, cost));
        if (!is_directed)
            edges[v].push_back(edge<T>(u, cost));
    }
};

template <class T>
vector<T> dijkstra(const graph<T> &g, const int start) {
    vector<T> dist(g.size());
    bool *used = new bool[g.size()]();
    priority_queue<pair<T, size_t>, vector<pair<T, size_t>>, greater<pair<T, size_t>>> q;
    dist[start] = 0;
    q.push(pair<T, size_t>(dist[start], start));
    used[start] = true;
    while (!q.empty()) {
        T dist_v;
        size_t v;
        tie(dist_v, v) = q.top();
        q.pop();
        if (dist[v] < dist_v)
            continue;
        for (edge<T> e: g.edges[v]) {
            size_t w = e.to;
            T dist_v_w = dist_v + e.cost;
            if (!used[w] || dist[w] > dist_v_w) {
                dist[w] = dist_v_w;
                q.push(pair<T, size_t>(dist[w], w));
                used[w] = true;
            }
        }
    }
    delete [] used;
    return dist;
}

template <class T>
T diameter_of_tree(const graph<T> &g) {
    size_t n = g.size();
    vector<T> dist_from_0 = dijkstra(g, 0);
    size_t v = 0;
    T dist_from_0_max = 0;
    for (size_t w = 1; w < n; ++w) {
        if (dist_from_0_max < dist_from_0[w]) {
            dist_from_0_max = dist_from_0[w];
            v = w;
        }
    }
    vector<T> dist_from_v = dijkstra(g, v);
    return *max_element(dist_from_v.begin(), dist_from_v.end());
}

int main(void) {
    int n;
    cin >> n;
    graph<int> g(n, false);
    for (int i = 0; i < n - 1; ++i) {
        int s, t, w;
        cin >> s >> t >> w;
        g.make_edge(s, t, w);
    }
    cout << diameter_of_tree(g) << endl;
    return 0;
}