//n代表树的节点数量 //children[i]表示i的子节点 var pa = make([][]int, n) var branch = make([][]int, n) //记录一条分支中的所有节点 var initPa func(int, int) //i为节点下标,d为节点深度 initPa = func(i int, d int) { branch[d] = i for x := 0; d-(1<<x) >= 0; x++ { pa[i] = append(pa[i], branch[d-(1<<x)]) } for _, v := range children[i] { initPa(v, d+1) } }
//depth表示节点的深度 if depth[i] > depth[j] { h := depth[i] - depth[j] m := bits.Len(uint(h)) for k := range m { if (h >> k & 1) == 1 { i = pa[i][k] } } } else { h := depth[j] - depth[i] m := bits.Len(unit(h)) for k := range m { if (h >> k & 1) == 1 { j = pa[j][k] } } }
//若i,j在同一子树上,则统一深度后相遇,此时直接得出结果 if i == j { return i } for x := len(pa[i]) - 1; x >= 0; x-- { if pa[i][x] != pa[j][x] { i, j = pa[i][x], pa[j][x] x = len(pa[i]) } } return pa[i][0]
//n代表树的节点数量 //children[i]表示i的子节点 var pa = make([][]int, n) var branch = make([][]int, n) //记录一条分支中的所有节点 var initPa func(int, int) //i为节点下标,d为节点深度 initPa = func(i int, d int) { branch[d] = i for x := 0; d-(1<<x) >= 0; x++ { pa[i] = append(pa[i], branch[d-(1<<x)]) } for _, v := range children[i] { initPa(v, d+1) } } initPa(0, 0) funclca(i int, j int, children [][]int, depth []int)int { if depth[i] > depth[j] { h := depth[i] - depth[j] m := bits.Len(uint(h)) for k := range m { if (h >> k & 1) == 1 { i = pa[i][k] } } } else { h := depth[j] - depth[i] m := bits.Len(unit(h)) for k := range m { if (h >> k & 1) == 1 { j = pa[j][k] } } } if i == j { return i } for x := len(pa[i]) - 1; x >= 0; x-- { if pa[i][x] != pa[j][x] { i, j = pa[i][x], pa[j][x] x = len(pa[i]) } } return pa[i][0] }