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
| class Solution { private static final int M = 14;
public int[] minOperationsQueries(int n, int[][] edges, int[][] queries) { List<int[]>[] g = new List[n]; Arrays.setAll(g, k -> new ArrayList<>()); for (int[] e : edges) { int u = e[0], v = e[1], w = e[2] - 1; g[u].add(new int[]{v, w}); g[v].add(new int[]{u, w}); } int[] depth = new int[n]; int[][] cnt = new int[n][26]; int[][] parent = new int[M][n]; dfs(0, -1, g, depth, parent, cnt); int k = queries.length; int[] ans = new int[k]; while (k-- != 0) { int x = queries[k][0], y = queries[k][1]; int z = lca(x, y, depth, parent), max = 0; for (int i = 0; i < 26; i++) { max = Math.max(max, cnt[x][i] + cnt[y][i] - 2 * cnt[z][i]); } ans[k] = depth[x] + depth[y] - 2 * depth[z] - max; } return ans; }
private void dfs(int x, int fa, List<int[]>[] g, int[] depth, int[][] parent, int[][] cnt) { for (int i = 1; 1 << i <= depth[x]; i++) { parent[i][x] = parent[i - 1][parent[i - 1][x]]; } for (int[] t : g[x]) { int y = t[0], w = t[1]; if (y != fa) { parent[0][y] = x; System.arraycopy(cnt[x], 0, cnt[y], 0, 26); cnt[y][w]++; depth[y] = depth[x] + 1; dfs(y, x, g, depth, parent, cnt); } } }
private int lca(int x, int y, int[] depth, int[][] parent) { if (depth[x] > depth[y]) { int t = x; x = y; y = t; } int step = depth[y] - depth[x]; for (int i = 0; i < 32; i++) { if ((step >> i & 1) != 0) { y = parent[i][y]; } } if (x != y) { for (int i = M - 1; i >= 0; i--) { int px = parent[i][x], py = parent[i][y]; if (px != py) { x = px; y = py; } } x = parent[0][x]; } return x; } }
|