-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathCentroidDecomposition.java
More file actions
99 lines (89 loc) · 2.6 KB
/
CentroidDecomposition.java
File metadata and controls
99 lines (89 loc) · 2.6 KB
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
class CentroidDecomposition implements Runnable {
public static void main(String[] args) throws Exception {
new Thread(null, new Main(), "threadname", (1L << 24)).start();
}
public void run(){
try{solve();}
catch(Exception e){}
}
static int n, k, out, max = Integer.MAX_VALUE / 2, currIt;
static ArrayDeque[] edges;
static int[] size;
static boolean[] del;
static int[] minL, it;
static ArrayList<Integer> cds, cls;
static void solve() throws Exception {
edges = new ArrayDeque[n];
for(int i = 0; i < n; ++i) edges[i] = new ArrayDeque<>();
del = new boolean[n];
minL = new int[k + 1];
it = new int[k + 1];
Arrays.fill(it, -1);
currIt = -1;
size = new int[n];
cds = new ArrayList<>();
cls = new ArrayList<>();
out = max;
go(0);
}
static void go(int idx){
dfs1(idx, -1);
int root = getCentroid(idx, -1, size[idx]);
++currIt;
it[0] = currIt;
minL[0] = 0;
dfs2(root, -1, 0, 0);
del[root] = true;
for(edge e : (ArrayDeque<edge>) edges[root]){
if(!del[e.v]) go(e.v);
}
}
static void dfs2(int idx, int par, int d, int l){
cds.add(d);
cls.add(l);
int need = k - d;
if(it[need] != currIt){
it[need] = currIt;
minL[need] = max;
}
int currL = l + minL[need];
out = Math.min(out, currL);
for(edge e : (ArrayDeque<edge>) edges[idx]){
if(!del[e.v] && e.v != par && d + e.w <= k){
dfs2(e.v, idx, d + e.w, l + 1);
if(par == -1){
for(int i = 0; i < cds.size(); ++i){
int cd = cds.get(i), cl = cls.get(i);
if(it[cd] != currIt){
it[cd] = currIt;
minL[cd] = max;
}
if(cl < minL[cd]) minL[cd] = cl;
}
cds.clear();
cls.clear();
}
}
}
}
static int getCentroid(int idx, int par, int totSize){
for(edge e : (ArrayDeque<edge>) edges[idx]){
if(!del[e.v] && e.v != par && size[e.v] * 2 > totSize) return getCentroid(e.v, idx, totSize);
}
return idx;
}
static int dfs1(int idx, int par){
int out = 1;
for(edge e : (ArrayDeque<edge>) edges[idx]){
if(!del[e.v] && e.v != par) out += dfs1(e.v, idx);
}
return size[idx] = out;
}
static class edge{
int v, w;
edge(int vv, int ww){
v = vv;
w = ww;
}
}
}