-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path0846-树的重心.go
91 lines (79 loc) · 1.37 KB
/
0846-树的重心.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package main
import "fmt"
const (
// 输入规模
N = 100010
// 邻接表存储无向无无环连通图(树),每个点都会存储两次
M = 2 * N
)
var (
// 存储n个邻接表的头指针
h [N]int
// 单链表的值
e [M]int
// 单链表的next指针
ne [M]int
// 单链表的可用指针
idx int
// 输入的树的结点数
n int
// 表示以每一个点为重心的剩余各个连通块中点数的最大值
// 中的最小值
ans = N
// 记录节点是否被访问过,访问过则标记为true
st [N]bool
)
// 以a为头结点的单链表中插入b
func add(a int, b int) {
e[idx] = b
ne[idx] = h[a]
h[a] = idx
idx++
}
func dfs(u int) int {
// 表示以u为重心的剩余各个连通块中点数的最大值
res := 0
st[u] = true
// 存储以u为根的树的节点数, 包括u
sum := 1
for i := h[u]; i != -1; i = ne[i] {
j := e[i]
if !st[j] {
s := dfs(j)
res = max(res, s)
sum += s
}
}
res = max(res, n-sum)
ans = min(res, ans)
return sum
}
func max(a, b int) int {
if a > b {
return a
} else {
return b
}
}
func min(a, b int) int {
if a < b {
return a
} else {
return b
}
}
func main() {
for i := 0; i < len(h); i++ {
h[i] = -1
}
fmt.Scan(&n)
for i := 0; i < n-1; i++ {
var a, b int
fmt.Scan(&a, &b)
add(a, b)
add(b, a)
}
// 可以任意选定一个节点开始 0< u <=n
dfs(1)
fmt.Println(ans)
}