树的直径:树上最长的简单路径。
算法思想:
1.dfs
通过两遍dfs,第1遍dfs,从任意点P出发,寻找离它最远的点Q 。第2遍dfs,从Q出发,找离它最远的点W。QW就是树的一条直径
2.树形dp
找到每个根节点的最长长度和次长长度,因为最长长度一定会经过某一个根节点
参考文章
zhuanlan.zhihu.com/p/115966044
两种算法的代码实现
1.dfs
func maxDistance(relations [][]interface{}) int {
edges := make(map[interface{}]map[interface{}]int, 0)
for _, relation := range relations {
u, v, w := relation[0], relation[1], relation[2].(int)
if _, ok := edges[u]; !ok {
edges[u] = make(map[interface{}]int, 0)
}
edges[u][v] = w
if _, ok := edges[v]; !ok {
edges[v] = make(map[interface{}]int, 0)
}
edges[v][u] = w
}
var dfs func(x interface{}, vis map[interface{}]int) (interface{}, int)
dfs = func(x interface{}, vis map[interface{}]int) (interface{}, int) {
_, ok := vis[x]
if ok {
return x, vis[x]
}
retPoint := x
retD := 0
vis[x] = retD
for v, w := range edges[x] {
if _, ok := vis[v]; !ok {
q, tmp := dfs(v, vis)
if tmp+w > retD {
retPoint = q
retD = tmp + w
}
}
}
vis[x] = retD
return retPoint, retD
}
var q interface{}
if len(relations) > 0 {
u := relations[0][0]
vis := make(map[interface{}]int, 0)
q, _ = dfs(u, vis)
}
vis := make(map[interface{}]int, 0)
p, ret := dfs(q, vis)
fmt.Println("point:", q, p)
fmt.Println("distance:", ret)
return ret
}
2.树形dp
func maxDistance1(relations [][]interface{}) int {
edges := make(map[interface{}]map[interface{}]int, 0)
for _, relation := range relations {
u, v, w := relation[0], relation[1], relation[2].(int)
if _, ok := edges[u]; !ok {
edges[u] = make(map[interface{}]int, 0)
}
edges[u][v] = w
if _, ok := edges[v]; !ok {
edges[v] = make(map[interface{}]int, 0)
}
edges[v][u] = w
}
var dfs func(x interface{}, vis map[interface{}][]int) []int
dfs = func(x interface{}, vis map[interface{}][]int) []int {
_, ok := vis[x]
if ok {
return vis[x]
}
fn := func(a, b, c, d int, w int) (int, int) {
first, second := a, b
if c+w < b {
} else if c+w < a && c+w > b {
second = c + w
} else if c+w > a {
second = first
first = c + w
} else if c+w < a && d+w < b {
first = c + w
second = b
}
return first, second
}
retD := []int{0, 0}
vis[x] = retD
for v, w := range edges[x] {
if _, ok := vis[v]; !ok {
tmp := dfs(v, vis)
first, second := fn(vis[x][0], vis[x][1], tmp[0], tmp[1], w)
vis[x][0] = first
vis[x][1] = second
}
}
return retD
}
vis := make(map[interface{}][]int, 0)
if len(relations) > 0 {
u := relations[0][0]
dfs(u, vis)
}
d := 0
for _, val := range vis {
if val[0]+val[1] > d {
d = val[0] + val[1]
}
}
fmt.Println("distance:", d)
return d
}
测试
func main() {
maxDistance([][]interface{}{[]interface{}{0, 1, 3}, []interface{}{0, 2, 1}, []interface{}{1, 3, 1}, []interface{}{1, 4, 4}, []interface{}{1, 5, 2}, []interface{}{2, 8, 7}, []interface{}{5, 6, 5}, []interface{}{5, 7, 6}, []interface{}{8, 9, 2}, []interface{}{8, 10, 8}})
maxDistance([][]interface{}{[]interface{}{"B", "D", 1}, []interface{}{"B", "E", 4}, []interface{}{"B", "F", 2}, []interface{}{"F", "G", 5}, []interface{}{"F", "H", 6}})
maxDistance1([][]interface{}{[]interface{}{0, 1, 3}, []interface{}{0, 2, 1}, []interface{}{1, 3, 1}, []interface{}{1, 4, 4}, []interface{}{1, 5, 2}, []interface{}{2, 8, 7}, []interface{}{5, 6, 5}, []interface{}{5, 7, 6}, []interface{}{8, 9, 2}, []interface{}{8, 10, 8}})
maxDistance1([][]interface{}{[]interface{}{"B", "D", 1}, []interface{}{"B", "E", 4}, []interface{}{"B", "F", 2}, []interface{}{"F", "G", 5}, []interface{}{"F", "H", 6}})
}
输出
point: 10 7
distance: 27
point: H E
distance: 12
distance: 27
distance: 12