Skip to content

Commit a659dbd

Browse files
committed
2322. Minimum Score After Removals on a Tree
1 parent ebc8580 commit a659dbd

1 file changed

Lines changed: 110 additions & 0 deletions

File tree

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
1. 아이디어: 트리 구조 원리 사용
3+
주어진 노드와 간선을 트리 구조로 저장하여 루트를 0으로 잡고 탐색
4+
5+
이때 각 노드를 루트로하는 XOR연산의 합을 미리 계산
6+
7+
이후, edges[][]를 완전탐색하여 2개의 제거할 간선을 고르고, 3개의 경우의 수를 기준으로 값을 계산
8+
9+
2. 시간복잡도: O(E) + O(V^2) + O(E^2) => O(V^2) (V ~= E)
10+
11+
3. 자료구조/알고리즘: DFS, Tree
12+
13+
*/
14+
15+
class Solution {
16+
private List<List<Integer>> tree = new ArrayList<>();
17+
private int n;
18+
private int[] xorSum;
19+
private int[] depths;
20+
private boolean[][] isAncestor;
21+
22+
public int minimumScore(int[] nums, int[][] edges) {
23+
// 모든 연결된 간선중 2개 제거
24+
// 가능한 모든 경우의 수 중 최소 점수
25+
26+
int ans = Integer.MAX_VALUE;
27+
n = nums.length;
28+
// 각 노드 기준 모든 서브트리의 xor값
29+
xorSum = new int[n];
30+
// 루트 기준 떨어진 길이
31+
depths = new int[n];
32+
// 조상 여부
33+
isAncestor = new boolean[n][n];
34+
35+
for(int i=0; i<n; i++) {
36+
tree.add(new ArrayList<>());
37+
}
38+
for(int[] edge : edges) {
39+
int a = edge[0];
40+
int b = edge[1];
41+
42+
tree.get(a).add(b);
43+
tree.get(b).add(a);
44+
}
45+
46+
// 각 노드기준 모든 xor연산 합 계산
47+
dfs(0, -1, nums, 0);
48+
49+
for(int i=0; i<edges.length-1; i++) {
50+
for(int j=i+1; j<edges.length; j++) {
51+
int[] edge1 = edges[i];
52+
int[] edge2 = edges[j];
53+
54+
int child1 = depths[edge1[0]] > depths[edge1[1]] ? edge1[0] : edge1[1];
55+
int child2 = depths[edge2[0]] > depths[edge2[1]] ? edge2[0] : edge2[1];
56+
57+
int a= xorSum[child1];
58+
int b= xorSum[child2];
59+
int c= xorSum[0];
60+
61+
if(isAncestor[child1][child2]) {
62+
//xorSum[child2]
63+
//xorSum[child1]^xorSum[child2]
64+
//xorSum[0]^xorSum[child1]
65+
66+
a ^= xorSum[child2];
67+
c ^= xorSum[child1];
68+
}
69+
else if(isAncestor[child2][child1]) {
70+
//xorSum[child1]
71+
//xorSum[child2]^xorSum[child1]
72+
//xorSum[0]^xorSum[child2]
73+
74+
b ^= xorSum[child1];
75+
c ^= xorSum[child2];
76+
}
77+
else {
78+
//xorSum[child1]
79+
//xorSum[child2]
80+
//xorSum[0]^xorSum[child1]^xorSum[child2]
81+
82+
c = c^a^b;
83+
}
84+
85+
ans = Math.min(ans, Math.max(a,Math.max(b,c)) - Math.min(a,Math.min(b,c)));
86+
if(ans == 0) return 0;
87+
}
88+
}
89+
90+
return ans;
91+
}
92+
93+
private int dfs(int curr, int parent, int[]nums, int depth) {
94+
int currXor = nums[curr];
95+
depths[curr] = depth;
96+
97+
for(int next : tree.get(curr)) {
98+
if(next == parent) continue;
99+
100+
for(int i = 0; i < n; i++) {
101+
if(isAncestor[i][curr]) isAncestor[i][next] = true;
102+
}
103+
isAncestor[curr][next] = true;
104+
currXor ^= dfs(next, curr, nums, depth+1);
105+
}
106+
107+
xorSum[curr] = currXor;
108+
return currXor;
109+
}
110+
}

0 commit comments

Comments
 (0)