← Home
```go
package main

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

type Edge struct {
	to int
	id int
}

var (
	n          int
	adj        [][]Edge
	U, V       []int
	sz         []int
	best       int
	centroid   int
	parent     []int
	parentEdge []int
	val        []int
	weights    []int
	stepB      int
)

func dfsCentroid(v, p int) {
	sz[v] = 1
	maxPart := 0
	for _, e := range adj[v] {
		if e.to == p {
			continue
		}
		dfsCentroid(e.to, v)
		sz[v] += sz[e.to]
		if sz[e.to] > maxPart {
			maxPart = sz[e.to]
		}
	}
	if n-sz[v] > maxPart {
		maxPart = n - sz[v]
	}
	if maxPart < best {
		best = maxPart
		centroid = v
	}
}

func dfsRoot(v, p int) {
	parent[v] = p
	sz[v] = 1
	for _, e := range adj[v] {
		if e.to == p {
			continue
		}
		parentEdge[e.to] = e.id
		dfsRoot(e.to, v)
		sz[v] += sz[e.to]
	}
}

func assignA(v, p int, counter *int) {
	val[v] = *counter
	*counter = *counter + 1
	weights[parentEdge[v]] = val[v] - val[p]
	for _, e := range adj[v] {
		if e.to == p {
			continue
		}
		assignA(e.to, v, counter)
	}
}

func assignB(v, p int, counter *int) {
	val[v] = (*counter) * stepB
	*counter = *counter + 1
	weights[parentEdge[v]] = val[v] - val[p]
	for _, e := range adj[v] {
		if e.to == p {
			continue
		}
		assignB(e.to, v, counter)
	}
}

func main() {
	in := bufio.NewReader(os.Stdin)
	fmt.Fscan(in, &n)

	if n == 1 {
		return
	}

	adj = make([][]Edge, n+1)
	m := n - 1
	U = make([]int, m)
	V = make([]int, m)
	weights = make([]int, m)

	for i := 0; i < m; i++ {
		fmt.Fscan(in, &U[i], &V[i])
		u, v := U[i], V[i]
		adj[u] = append(adj[u], Edge{v, i})
		adj[v] = append(adj[v], Edge{u, i})
	}

	sz = make([]int, n+1)
	best = n + 1
	centroid = 1
	dfsCentroid(1, 0)

	parent = make([]int, n+1)
	parentEdge = make([]int, n+1)
	sz = make([]int, n+1)
	dfsRoot(centroid, 0)

	children := make([]int, 0)
	sizes := make([]int, 0)
	for _, e := range adj[centroid] {
		children = append(children, e.to)
		sizes = append(sizes, sz[e.to])
	}

	k := len(children)
	limit := n

	prev := make([][]int, k+1)
	take := make([][]bool, k+1)
	for i := 0; i <= k; i++ {
		prev[i] = make([]int, limit+1)
		take[i] = make([]bool, limit+1)
		for s := 0; s <= limit; s++ {
			prev[i][s] = -1
		}
	}
	prev[0][0] = 0

	for i := 0; i < k; i++ {
		w := sizes[i]
		for s := 0; s <= limit; s++ {
			if prev[i][s] == -1 {
				continue
			}
			if prev[i+1][s] == -1 {
				prev[i+1][s] = s
				take[i+1][s] = false
			}
			if s+w <= limit && prev[i+1][s+w] == -1 {
				prev[i+1][s+w] = s
				take[i+1][s+w] = true
			}
		}
	}

	target := -1
	bestCover := -1
	for s := 0; s <= n-1; s++ {
		if prev[k][s] == -1 {
			continue
		}
		cover := (s + 1) * (n - s) - 1
		if cover > bestCover {
			bestCover = cover
			target = s
		}
	}

	selectedChild := make([]bool, n+1)
	cur := target
	for i := k; i >= 1; i-- {
		if take[i][cur] {
			selectedChild[children[i-1]] = true
		}
		cur = prev[i][cur]
	}

	a := target + 1
	val = make([]int, n+1)
	val[centroid] = 0

	counterA := 1
	for _, child := range children {
		if selectedChild[child] {
			assignA(child, centroid, &counterA)
		}
	}

	stepB = a
	counterB := 1
	for _, child := range children {
		if !selectedChild[child] {
			assignB(child, centroid, &counterB)
		}
	}

	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()
	for i := 0; i < m; i++ {
		fmt.Fprintln(out, U[i], V[i], weights[i])
	}
}
```