import
java.util.ArrayList;
import
java.util.Arrays;
import
java.util.List;
public
class
CentroidDecomposition {
static
final
int
MAXN =
1025
;
static
List<Integer>[] tree =
new
ArrayList[MAXN];
static
List<Integer>[] centroidTree =
new
ArrayList[MAXN];
static
boolean
[] centroidMarked =
new
boolean
[MAXN];
static
void
addEdge(
int
u,
int
v) {
tree[u].add(v);
tree[v].add(u);
}
static
void
DFS(
int
src,
boolean
[] visited,
int
[] subtreeSize,
int
[] n) {
visited[src] =
true
;
n[
0
]++;
subtreeSize[src] =
1
;
for
(
int
neighbor : tree[src]) {
if
(!visited[neighbor] && !centroidMarked[neighbor]) {
DFS(neighbor, visited, subtreeSize, n);
subtreeSize[src] += subtreeSize[neighbor];
}
}
}
static
int
getCentroid(
int
src) {
boolean
[] visited =
new
boolean
[MAXN];
int
[] subtreeSize =
new
int
[MAXN];
Arrays.fill(visited,
false
);
Arrays.fill(subtreeSize,
0
);
int
[] n = {
0
};
DFS(src, visited, subtreeSize, n);
Arrays.fill(visited,
false
);
int
centroid = getCentroid(src, visited, subtreeSize, n[
0
]);
centroidMarked[centroid] =
true
;
return
centroid;
}
static
int
getCentroid(
int
src,
boolean
[] visited,
int
[] subtreeSize,
int
n) {
boolean
isCentroid =
true
;
visited[src] =
true
;
int
heaviestChild =
0
;
for
(
int
neighbor : tree[src]) {
if
(!visited[neighbor] && !centroidMarked[neighbor]) {
if
(subtreeSize[neighbor] > n /
2
)
isCentroid =
false
;
if
(heaviestChild ==
0
|| subtreeSize[neighbor] > subtreeSize[heaviestChild])
heaviestChild = neighbor;
}
}
if
(isCentroid && n - subtreeSize[src] <= n /
2
)
return
src;
return
getCentroid(heaviestChild, visited, subtreeSize, n);
}
static
int
decomposeTree(
int
root) {
int
cendTree = getCentroid(root);
System.out.print(cendTree +
" "
);
for
(
int
neighbor : tree[cendTree]) {
if
(!centroidMarked[neighbor]) {
int
cendSubtree = decomposeTree(neighbor);
centroidTree[cendTree].add(cendSubtree);
centroidTree[cendSubtree].add(cendTree);
}
}
return
cendTree;
}
public
static
void
main(String[] args) {
int
n =
16
;
for
(
int
i =
0
; i < MAXN; i++) {
tree[i] =
new
ArrayList<>();
centroidTree[i] =
new
ArrayList<>();
}
addEdge(
1
,
4
);
addEdge(
2
,
4
);
addEdge(
3
,
4
);
addEdge(
4
,
5
);
addEdge(
5
,
6
);
addEdge(
6
,
7
);
addEdge(
7
,
8
);
addEdge(
7
,
9
);
addEdge(
6
,
10
);
addEdge(
10
,
11
);
addEdge(
11
,
12
);
addEdge(
11
,
13
);
addEdge(
12
,
14
);
addEdge(
13
,
15
);
addEdge(
13
,
16
);
decomposeTree(
1
);
}
}