classSolution: defminimumScore(self, nums: List[int], edges: List[List[int]]) -> int: n = len(nums) g = [[] for _ inrange(n)] for x, y in edges: g[x].append(y) g[y].append(x)
xor, in_, out, clock = [0] * n, [0] * n, [0] * n, 0 defdfs(x: int, fa: int) -> None: nonlocal clock clock += 1 in_[x] = clock xor[x] = nums[x] for y in g[x]: if y != fa: dfs(y, x) xor[x] ^= xor[y] out[x] = clock dfs(0, -1)
ans = inf for i inrange(2, n): for j inrange(1, i): if in_[i] < in_[j] <= out[i]: # i 是 j 的祖先节点 x, y, z = xor[j], xor[i] ^ xor[j], xor[0] ^ xor[i] elif in_[j] < in_[i] <= out[j]: # j 是 i 的祖先节点 x, y, z = xor[i], xor[i] ^ xor[j], xor[0] ^ xor[j] else: # 删除的两条边分别属于两颗不相交的子树 x, y, z = xor[i], xor[j], xor[0] ^ xor[i] ^ xor[j] ans = min(ans, max(x, y, z) - min(x, y, z)) # 注:把 min max 拆开,改为下面的注释,可以明显加快速度 # mn = mx = x # if y < mn: mn = y # elif y > mx: mx = y # if z < mn: mn = z # elif z > mx: mx = z # if mx - mn < ans: ans = mx - mn if ans == 0: return0# 提前退出 return ans
classSolution { public: intminimumScore(vector<int> &nums, vector<vector<int>> &edges){ int n = nums.size(); vector<vector<int>> g(n); for (auto &e : edges) { int x = e[0], y = e[1]; g[x].push_back(y); g[y].push_back(x); }
int xr[n], in[n], out[n], clock = 0; function<void(int, int)> dfs = [&](int x, int fa) { in[x] = ++clock; xr[x] = nums[x]; for (int y : g[x]) if (y != fa) { dfs(y, x); xr[x] ^= xr[y]; } out[x] = clock; }; dfs(0, -1);
int ans = INT_MAX; for (int i = 2, x, y, z; i < n; ++i) for (int j = 1; j < i; ++j) { if (in[i] < in[j] && in[j] <= out[i]) x = xr[j], y = xr[i] ^ x, z = xr[0] ^ xr[i]; // i 是 j 的祖先节点 elseif (in[j] < in[i] && in[i] <= out[j]) x = xr[i], y = xr[j] ^ x, z = xr[0] ^ xr[j]; // j 是 i 的祖先节点 else x = xr[i], y = xr[j], z = xr[0] ^ x ^ y; // 删除的两条边分别属于两颗不相交的子树 ans = min(ans, max(max(x, y), z) - min(min(x, y), z)); if (ans == 0) return0; // 提前退出 } return ans; } };
funcminimumScore(nums []int, edges [][]int)int { n := len(nums) g := make([][]int, n) for _, e := range edges { x, y := e[0], e[1] g[x] = append(g[x], y) g[y] = append(g[y], x) }
xor := make([]int, n) in := make([]int, n) out := make([]int, n) clock := 0 var dfs func(int, int) dfs = func(x, fa int) { clock++ in[x] = clock xor[x] = nums[x] for _, y := range g[x] { if y != fa { dfs(y, x) xor[x] ^= xor[y] } } out[x] = clock } dfs(0, -1) isAncestor := func(x, y int)bool { return in[x] < in[y] && in[y] <= out[x] }
ans := math.MaxInt32 for i := 2; i < n; i++ { for j := 1; j < i; j++ { var x, y, z int if isAncestor(i, j) { // i 是 j 的祖先节点 x, y, z = xor[j], xor[i]^xor[j], xor[0]^xor[i] } elseif isAncestor(j, i) { // j 是 i 的祖先节点 x, y, z = xor[i], xor[i]^xor[j], xor[0]^xor[j] } else { // 删除的两条边分别属于两颗不相交的子树 x, y, z = xor[i], xor[j], xor[0]^xor[i]^xor[j] } ans = min(ans, max(max(x, y), z)-min(min(x, y), z)) if ans == 0 { return0// 提前退出 } } } return ans }
funcmin(a, b int)int { if a > b { return b }; return a } funcmax(a, b int)int { if a < b { return b }; return a }