-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathLowerBound.java
88 lines (81 loc) · 2.04 KB
/
LowerBound.java
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
import static java.util.Arrays.*;
import tc.wata.debug.*;
public class LowerBound {
public static int LEVEL = 3;
public static int lowerBound(Graph g) {
int lb = g.k;
if (LEVEL == 2) lb = degree(g);
else if (LEVEL == 3) lb = degreeEx(g);
return lb;
}
public static int degree(Graph g) {
int[] deg = new int[g.n];
int n = 0, p = 0, m = 0;
for (int i = 0; i < g.n; i++) if (g.adj[i].length > 0) {
n++;
m += g.adj[i].length;
if (g.used[i] != 'F') deg[p++] = g.adj[i].length;
}
m /= 2;
if (n == 0 || m < n) return g.k;
sort(deg, 0, p);
int sum = 0;
for (int k = 1; ; k++) {
sum += deg[p - k];
if (sum - k > m - n) return k + g.k;
}
}
public static int degreeEx(Graph g) {
int k = 0, sum = 0;
int n = 0, p = 0, m = 0;
int[] deg = new int[g.n];
boolean[] adjF = new boolean[g.n];
for (int s = 0; s < g.n; s++) if (g.adj[s].length > 0 && g.used[s] == 'F') {
for (int v : g.adj[s]) adjF[v] = true;
}
long[] ls = new long[g.n];
for (int i = 0; i < g.n; i++) if (g.adj[i].length > 0) {
m += g.adj[i].length;
ls[n++] = ((long)g.adj[i].length) << 32 | i;
}
sort(ls, 0, n);
int[] num = new int[g.n];
boolean[] match = new boolean[g.n], used = new boolean[g.n];
for (int i = 0; i < n; i++) {
int v = (int)ls[i];
used[v] = true;
if (g.used[v] != 'F') {
int t = -1;
for (int j = 0; j < g.adj[v].length; j++) if (!match[g.adj[v][j]] && g.used[g.adj[v][j]] == 0) {
int u = g.adj[v][j];
if (j + 1 < g.adj[v].length && g.adj[v][j + 1] == u || adjF[v] && adjF[u]) {
if (!used[u]) {
num[v]++;
} else {
num[u]--;
if (t < 0 || num[t] > num[u]) t = u;
}
if (j + 1 < g.adj[v].length && g.adj[v][j + 1] == u) j++;
}
}
if (t >= 0) {
match[v] = match[t] = true;
k++;
sum += g.adj[v].length;
} else {
deg[p++] = g.adj[v].length;
}
}
}
m /= 2;
if (n == 0 || m < n) return g.k;
for (int k0 = 0; ; ) {
if (sum - k > m - n) {
return k + g.k;
}
k++;
k0++;
sum += deg[p - k0];
}
}
}