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

package main

// http://www.prefield.com/algorithm/graph/tree_diameter.html

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var infty = 1000000000

var scanner = bufio.NewScanner(os.Stdin)

func nextString() string {
	scanner.Scan()
	return scanner.Text()
}

type DirectedGraphNodeID int

func newDirectedGraph(nNodes int) *DirectedGraph {
	graph := DirectedGraph{}

	graph.nodes = make([]*DirectedGraphNode, nNodes)
	for iNode := 0; iNode < nNodes; iNode++ {
		graph.nodes[iNode] = &DirectedGraphNode{
			key:       DirectedGraphNodeID(iNode),
			adjacents: map[DirectedGraphNodeID]*DirectedGraphNode{},
			costs:     map[DirectedGraphNodeID]int{},
			d:         infty,
		}
	}

	return &graph
}

type DirectedGraph struct {
	nodes []*DirectedGraphNode
	time  int
}

func (graph *DirectedGraph) sedAdjacent(leftID, rightID DirectedGraphNodeID, weight int) {
	graph.nodes[leftID].adjacents[rightID] = graph.nodes[rightID]
	graph.nodes[leftID].costs[rightID] = weight
}

type DirectedGraphNode struct {
	key       DirectedGraphNodeID
	adjacents map[DirectedGraphNodeID]*DirectedGraphNode
	costs     map[DirectedGraphNodeID]int

	parent   *DirectedGraphNode
	d, f     int
	visitied bool
	distance int
}

func dfsVisit(graph *DirectedGraph, startNode *DirectedGraphNode) {
	graph.time++
	startNode.d = graph.time
	startNode.visitied = true

	for adjacentID, adjacent := range startNode.adjacents {
		if !adjacent.visitied {
			adjacent.parent = startNode
			adjacent.distance = startNode.distance + startNode.costs[adjacentID]
			dfsVisit(graph, adjacent)
		}
	}
	graph.time++
	startNode.f = graph.time
}

func fillDistances(graph *DirectedGraph, startNode *DirectedGraphNode) {
	for _, node := range graph.nodes {
		node.visitied = false
		node.parent = nil
		node.distance = infty
	}
	graph.time = 0
	startNode.distance = 0
	dfsVisit(graph, startNode)
}

func nextInt() int {
	n, err := strconv.Atoi(nextString())
	if err != nil {
		fmt.Printf("strconv.Atoi failed: %v\n", err)
	}
	return n
}

func getFarthestNode(graph *DirectedGraph) *DirectedGraphNode {
	maxDistance := 0
	var nodeMaxDistance *DirectedGraphNode
	for _, node := range graph.nodes {
		if node.distance >= maxDistance {
			maxDistance = node.distance
			nodeMaxDistance = node
		}
	}
	return nodeMaxDistance
}

func main() {
	scanner.Split(bufio.ScanWords)

	nNodes := nextInt()
	graph := newDirectedGraph(nNodes)
	for iNode := 0; iNode < nNodes-1; iNode++ {
		parent := DirectedGraphNodeID(nextInt())
		child := DirectedGraphNodeID(nextInt())
		weight := nextInt()
		graph.sedAdjacent(parent, child, weight)
		graph.sedAdjacent(child, parent, weight)
	}

	fillDistances(graph, graph.nodes[0])
	nodeMaxDistance := getFarthestNode(graph)
	// fmt.Println(nodeMaxDistance)

	fillDistances(graph, nodeMaxDistance)
	nodeMaxDistance = getFarthestNode(graph)
	fmt.Println(nodeMaxDistance.distance)
}