103 lines
2.4 KiB
Java
103 lines
2.4 KiB
Java
import java.util.Random;
|
|
|
|
public class Coloring {
|
|
|
|
int minColors;
|
|
int[] bestColoring;
|
|
|
|
public int minColors(boolean[][] graph) {
|
|
int n = graph.length;
|
|
bestColoring = new int[n];
|
|
int[] id = new int[n + 1];
|
|
int[] deg = new int[n + 1];
|
|
for (int i = 0; i <= n; i++)
|
|
id[i] = i;
|
|
bestColoring = new int[n];
|
|
int res = 1;
|
|
for (int from = 0, to = 1; to <= n; to++) {
|
|
int best = to;
|
|
for (int i = to; i < n; i++) {
|
|
if (graph[id[to - 1]][id[i]])
|
|
++deg[id[i]];
|
|
if (deg[id[best]] < deg[id[i]])
|
|
best = i;
|
|
}
|
|
int t = id[to];
|
|
id[to] = id[best];
|
|
id[best] = t;
|
|
if (deg[id[to]] == 0) {
|
|
minColors = n + 1;
|
|
dfs(graph, id, new int[n], from, to, from, 0);
|
|
from = to;
|
|
res = Math.max(res, minColors);
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
void dfs(boolean[][] graph, int[] id, int[] coloring, int from, int to, int cur, int usedColors) {
|
|
if (usedColors >= minColors)
|
|
return;
|
|
if (cur == to) {
|
|
for (int i = from; i < to; i++)
|
|
bestColoring[id[i]] = coloring[i];
|
|
minColors = usedColors;
|
|
return;
|
|
}
|
|
boolean[] used = new boolean[usedColors + 1];
|
|
for (int i = 0; i < cur; i++)
|
|
if (graph[id[cur]][id[i]])
|
|
used[coloring[i]] = true;
|
|
for (int i = 0; i <= usedColors; i++) {
|
|
if (!used[i]) {
|
|
int tmp = coloring[cur];
|
|
coloring[cur] = i;
|
|
dfs(graph, id, coloring, from, to, cur + 1, Math.max(usedColors, i + 1));
|
|
coloring[cur] = tmp;
|
|
}
|
|
}
|
|
}
|
|
|
|
// random test
|
|
public static void main(String[] args) {
|
|
Random rnd = new Random(1);
|
|
for (int step = 0; step < 1000; step++) {
|
|
int n = rnd.nextInt(10) + 1;
|
|
boolean[][] g = new boolean[n][n];
|
|
for (int i = 0; i < n; i++)
|
|
for (int j = 0; j < i; j++)
|
|
if (rnd.nextBoolean()) {
|
|
g[i][j] = true;
|
|
g[j][i] = true;
|
|
}
|
|
int res1 = new Coloring().minColors(g);
|
|
int res2 = colorSlow(g);
|
|
if (res1 != res2)
|
|
throw new RuntimeException();
|
|
}
|
|
}
|
|
|
|
static int colorSlow(boolean[][] g) {
|
|
int n = g.length;
|
|
for (int allowedColors = 1; ; allowedColors++) {
|
|
long colors = 1;
|
|
for (int i = 0; i < n; i++)
|
|
colors *= allowedColors;
|
|
m1:
|
|
for (long c = 0; c < colors; c++) {
|
|
int[] col = new int[n];
|
|
long cur = c;
|
|
for (int i = 0; i < n; i++) {
|
|
col[i] = (int) (cur % allowedColors);
|
|
cur /= allowedColors;
|
|
}
|
|
for (int i = 0; i < n; i++)
|
|
for (int j = 0; j < i; j++)
|
|
if (g[i][j] && col[i] == col[j])
|
|
continue m1;
|
|
return allowedColors;
|
|
}
|
|
}
|
|
}
|
|
}
|