-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy path1330 Nearest Common Ancestors - Tarjan.java
107 lines (106 loc) · 2.35 KB
/
1330 Nearest Common Ancestors - Tarjan.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
* MLE
*/
import java.io.*;
import java.util.*;
import java.math.*;
class TreeNode {
boolean isRoot;
boolean isVisited;
int value;
TreeNode ancestor;
TreeNode parent;
int rank;
List<TreeNode> children;
TreeNode(int value) {
this.value = value;
this.parent = this;
this.ancestor = this;
isRoot = true;
isVisited = false;
children = new ArrayList<TreeNode>();
}
}
public class Main {
private static int ret = 1;
private static StringBuilder sb = new StringBuilder();
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int testcase = in.nextInt();
while (testcase-- > 0) {
int size = in.nextInt();
TreeNode[] nodes = new TreeNode[size + 1];
ret = 1;
for (int index = 0; index <= size; ++index) {
nodes[index] = new TreeNode(index);
}
for (int index = 1; index < size; ++index) {
int parent = in.nextInt();
int child = in.nextInt();
nodes[child].isRoot = false;
nodes[parent].children.add(nodes[child]);
}
TreeNode root = null;
for (int index = 1; index <= size; ++index) {
if (nodes[index].isRoot) {
root = nodes[index];
break;
}
}
int u = in.nextInt();
int v = in.nextInt();
LCA(root, nodes[u], nodes[v]);
}
System.out.println(sb.toString());
}
private static TreeNode find(TreeNode x) {
if (x.parent.value == x.value) {
return x;
} else {
x.parent = find(x.parent);
return x.parent;
}
}
private static void union(TreeNode x, TreeNode y) {
TreeNode rootX = find(x);
TreeNode rootY = find(y);
if (rootX.value == rootY.value) {
return;
}
if (rootX.rank < rootY.rank) {
rootX.parent = rootY;
} else if (rootX.rank > rootY.rank) {
rootY.parent = rootX;
} else {
rootX.parent = rootY;
rootY.rank++;
}
}
private static void LCA(TreeNode root, TreeNode u, TreeNode v) {
if (root == null) {
return;
}
root.ancestor = root;
for (int i = 0; i < root.children.size(); ++i) {
LCA(root.children.get(i), u, v);
if (ret == 0) {
return;
}
union(root, root.children.get(i));
find(root).ancestor = root;
}
root.isVisited = true;
if (root == u && v.isVisited && ret == 1) {
sb.append(find(v).ancestor.value);
sb.append('\n');
ret = 0;
return;
}
if (root == v && u.isVisited && ret == 1) {
sb.append(find(u).ancestor.value);
sb.append('\n');
ret = 0;
return;
}
}
}