[LeetCode] Minimum Score After Removals on a Tree

2322. Minimum Score After Removals on a Tree

There is an undirected connected tree with n nodes labeled from 0 to n - 1 and n - 1 edges.

You are given a 0-indexed integer array nums of length n where nums[i] represents the value of the ith node. You are also given a 2D integer array edges of length n - 1 where edges[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the tree.

Remove two distinct edges of the tree to form three connected components. For a pair of removed edges, the following steps are defined:

  1. Get the XOR of all the values of the nodes for each of the three components respectively.
  2. The difference between the largest XOR value and the smallest XOR value is the score of the pair.
  • For example, say the three components have the node values: [4,5,7], [1,9], and [3,3,3]. The three XOR values are 4 ^ 5 ^ 7 = 6, 1 ^ 9 = 8, and 3 ^ 3 ^ 3 = 3. The largest XOR value is 8 and the smallest XOR value is 3. The score is then 8 - 3 = 5.

Return the minimum score of any possible pair of edge removals on the given tree.

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 {
int n;
vector<vector<int>> adj;
vector<int> val;
int LCA[1010][22];
int level[1000];

int dfs(vector<int>& A, int u, int par, int lvl = 0) {
val[u] = A[u];
level[u] = lvl;
LCA[u][0] = par;
for(auto& v : adj[u]) {
if(v == par) continue;
val[u] ^= dfs(A, v, u, lvl + 1);
}
return val[u];
}
void init() {
for(int j = 0; j < 21; j++) {
for(int i = 0; i < n; i++) {
if(LCA[i][j] == -1) continue;
LCA[i][j+1] = LCA[LCA[i][j]][j];
}
}
}
int query(int u, int v) {
if(level[u] < level[v]) swap(u, v);
int diff = level[u] - level[v];
for(int i = 0; diff; i++, diff/=2) {
if(diff&1) u = LCA[u][i];
}
if(u != v) {
for(int i = 21; i >= 0; i--) {
if(LCA[u][i] == LCA[v][i]) continue;
u = LCA[u][i];
v = LCA[v][i];
}
u = LCA[u][0];
}
return u;
}
public:
int minimumScore(vector<int>& A, vector<vector<int>>& edges) {
n = A.size();
adj = vector<vector<int>>(n);
val = vector<int>(n);
memset(LCA, -1, sizeof LCA);
memset(level, -1, sizeof level);
for(auto& e : edges) {
int u = e[0], v = e[1];
adj[u].push_back(v);
adj[v].push_back(u);
}
dfs(A,0,-1);
init();
int res = INT_MAX;
for(int i = 1; i < n; i++) {
for(int j = i + 1; j < n; j++) {
int lca = query(i,j);
int a, b, c;
if(lca == i) {
a = val[0] ^ val[i], b = val[i] ^ val[j], c = val[j];
} else if(lca == j) {
a = val[0] ^ val[j], b = val[j] ^ val[i], c = val[i];
} else {
a = val[0] ^ val[i] ^ val[j], b = val[i], c = val[j];
}
int ma = max({a,b,c}), mi = min({a,b,c});
res = min(res, ma - mi);
}
}
return res;
}
};
Author: Song Hayoung
Link: https://songhayoung.github.io/2022/06/26/PS/LeetCode/minimum-score-after-removals-on-a-tree/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.