-
Notifications
You must be signed in to change notification settings - Fork 522
/
PruferCode.java
89 lines (84 loc) · 2.59 KB
/
PruferCode.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
89
package combinatorics;
import java.util.*;
import java.util.stream.Stream;
// https://en.wikipedia.org/wiki/Pr%C3%BCfer_sequence
public class PruferCode {
// O(n) complexity
public static List<Integer>[] pruferCode2Tree(int[] pruferCode) {
int n = pruferCode.length + 2;
List<Integer>[] tree = Stream.generate(ArrayList::new).limit(n).toArray(List[] ::new);
int[] degree = new int[n];
Arrays.fill(degree, 1);
for (int v : pruferCode) ++degree[v];
int ptr = 0;
while (degree[ptr] != 1) ++ptr;
int leaf = ptr;
for (int v : pruferCode) {
tree[leaf].add(v);
tree[v].add(leaf);
--degree[leaf];
--degree[v];
if (degree[v] == 1 && v < ptr) {
leaf = v;
} else {
while (degree[++ptr] != 1)
;
leaf = ptr;
}
}
for (int v = 0; v < n - 1; v++) {
if (degree[v] == 1) {
tree[v].add(n - 1);
tree[n - 1].add(v);
}
}
return tree;
}
// precondition: n >= 2
// O(n) complexity
public static int[] tree2PruferCode(List<Integer>[] tree) {
int n = tree.length;
int[] parent = new int[n];
parent[n - 1] = -1;
pruferDfs(tree, parent, n - 1);
int[] degree = new int[n];
int ptr = -1;
for (int i = 0; i < n; ++i) {
degree[i] = tree[i].size();
if (degree[i] == 1 && ptr == -1)
ptr = i;
}
int[] res = new int[n - 2];
for (int i = 0, leaf = ptr; i < n - 2; ++i) {
int next = parent[leaf];
res[i] = next;
--degree[next];
if (degree[next] == 1 && next < ptr) {
leaf = next;
} else {
while (degree[++ptr] != 1)
;
leaf = ptr;
}
}
return res;
}
static void pruferDfs(List<Integer>[] tree, int[] parent, int u) {
for (int v : tree[u]) {
if (v != parent[u]) {
parent[v] = u;
pruferDfs(tree, parent, v);
}
}
}
// Usage example
public static void main(String[] args) {
int[] a = new int[5];
do {
List<Integer>[] tree = pruferCode2Tree(a);
int[] b = tree2PruferCode(tree);
if (!Arrays.equals(a, b))
throw new RuntimeException();
} while (Arrangements.nextArrangementWithRepeats(a, a.length + 2));
}
}