package main
import (
"bufio"
"io"
"os"
"strconv"
)
type Edge struct {
to int
weight int
}
func main() {
bytes, _ := io.ReadAll(os.Stdin)
var pos int
readInt := func() int {
for pos < len(bytes) && (bytes[pos] < '0' || bytes[pos] > '9') {
pos++
}
if pos >= len(bytes) {
return 0
}
res := 0
for pos < len(bytes) && bytes[pos] >= '0' && bytes[pos] <= '9' {
res = res*10 + int(bytes[pos]-'0')
pos++
}
return res
}
n := readInt()
if n == 0 {
return
}
graph := make([][]Edge, n+1)
degree := make([]int, n+1)
for i := 0; i < n; i++ {
u := readInt()
v := readInt()
w := readInt()
graph[u] = append(graph[u], Edge{v, w})
graph[v] = append(graph[v], Edge{u, w})
degree[u]++
degree[v]++
}
queue := make([]int, 0)
for i := 1; i <= n; i++ {
if degree[i] == 1 {
queue = append(queue, i)
}
}
inCycle := make([]bool, n+1)
for i := 1; i <= n; i++ {
inCycle[i] = true
}
for len(queue) > 0 {
u := queue[0]
queue = queue[1:]
inCycle[u] = false
for _, edge := range graph[u] {
v := edge.to
if inCycle[v] {
degree[v]--
if degree[v] == 1 {
queue = append(queue, v)
}
}
}
}
start := 0
for i := 1; i <= n; i++ {
if inCycle[i] {
start = i
break
}
}
cycle := make([]int, 0)
cycleEdges := make([]int64, 0)
curr := start
prev := 0
for {
cycle = append(cycle, curr)
next_node := 0
next_weight := 0
for _, edge := range graph[curr] {
v := edge.to
if inCycle[v] && v != prev {
next_node = v
next_weight = edge.weight
break
}
}
if next_node == start {
cycleEdges = append(cycleEdges, int64(next_weight))
break
}
cycleEdges = append(cycleEdges, int64(next_weight))
prev = curr
curr = next_node
}
size := make([]int64, n+1)
sumDistDown := make([]int64, n+1)
depth := make([]int64, n+1)
distTree := make([]int64, n+1)
var dfs1 func(u, p int, d int64)
dfs1 = func(u, p int, d int64) {
size[u] = 1
depth[u] = d
for _, edge := range graph[u] {
v := edge.to
if v != p && !inCycle[v] {
dfs1(v, u, d+int64(edge.weight))
size[u] += size[v]
sumDistDown[u] += sumDistDown[v] + int64(edge.weight)*size[v]
}
}
}
var dfs2 func(u, p int, totalSize int64)
dfs2 = func(u, p int, totalSize int64) {
for _, edge := range graph[u] {
v := edge.to
if v != p && !inCycle[v] {
distTree[v] = distTree[u] + int64(edge.weight)*(totalSize-2*size[v])
dfs2(v, u, totalSize)
}
}
}
for _, c := range cycle {
dfs1(c, 0, 0)
distTree[c] = sumDistDown[c]
dfs2(c, 0, size[c])
}
k := len(cycle)
C := make([]int, 2*k+1)
D := make([]int64, 2*k+1)
S := make([]int64, 2*k+1)
P := make([]int64, 2*k+1)
W_total := int64(0)
for i := 1; i <= k; i++ {
c := cycle[i-1]
C[i] = c
C[k+i] = c
D[i] = cycleEdges[i-1]
D[k+i] = cycleEdges[i-1]
S[i] = size[c]
S[k+i] = size[c]
W_total += distTree[c]
}
SumS := make([]int64, 2*k+1)
SumSP := make([]int64, 2*k+1)
P[1] = 0
for i := 2; i <= 2*k; i++ {
P[i] = P[i-1] + D[i-1]
}
for i := 1; i <= 2*k; i++ {
SumS[i] = SumS[i-1] + S[i]
SumSP[i] = SumSP[i-1] + S[i]*P[i]
}
L := P[k+1]
C_ans := make([]int64, k+1)
for i := 1; i <= k; i++ {
low, high := 0, k-1
r := 0
for low <= high {
mid := (low + high) / 2
if 2*(P[i+mid]-P[i]) <= L {
r = mid
low = mid + 1
} else {
high = mid - 1
}
}
term1 := int64(0)
a, b := i+1, i+r
if a <= b {
term1 = (SumSP[b] - SumSP[a-1]) - P[i]*(SumS[b]-SumS[a-1])
}
term2 := int64(0)
a2, b2 := i+r+1, i+k-1
if a2 <= b2 {
term2 = (L+P[i])*(SumS[b2]-SumS[a2-1]) - (SumSP[b2]-SumSP[a2-1])
}
D_val := term1 + term2
C_ans[i] = W_total - distTree[C[i]] + D_val
}
Total_ans := make([]int64, n+1)
var dfs3 func(u, p int, cAnsVal int64, Si int64)
dfs3 = func(u, p int, cAnsVal int64, Si int64) {
Total_ans[u] = distTree[u] + depth[u]*int64(n-int(Si)) + cAnsVal
for _, edge := range graph[u] {
v := edge.to
if v != p && !inCycle[v] {
dfs3(v, u, cAnsVal, Si)
}
}
}
for i := 1; i <= k; i++ {
c := C[i]
dfs3(c, 0, C_ans[i], S[i])
}
writer := bufio.NewWriter(os.Stdout)
for i := 1; i <= n; i++ {
if i > 1 {
writer.WriteByte(' ')
}
writer.WriteString(strconv.FormatInt(Total_ans[i], 10))
}
writer.WriteByte('\n')
writer.Flush()
}