-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSolution.java
136 lines (113 loc) · 3.96 KB
/
Solution.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
class SumInLeavesVisitor extends TreeVis {
private int result = 0;
public int getResult() {
return result;
}
public void visitNode(TreeNode node) {
// do nothing
}
public void visitLeaf(TreeLeaf leaf) {
result += leaf.getValue();
}
}
class ProductOfRedNodesVisitor extends TreeVis {
private long result = 1;
private final int M = 1000000007;
public int getResult() {
return (int) result;
}
public void visitNode(TreeNode node) {
if (node.getColor() == Color.RED) {
result = (result * node.getValue()) % M;
}
}
public void visitLeaf(TreeLeaf leaf) {
if (leaf.getColor() == Color.RED) {
result = (result * leaf.getValue()) % M;
}
}
}
class FancyVisitor extends TreeVis {
private int nonLeafEvenDepthSum = 0;
private int greenLeavesSum = 0;
public int getResult() {
return Math.abs(nonLeafEvenDepthSum - greenLeavesSum);
}
public void visitNode(TreeNode node) {
if (node.getDepth() % 2 == 0) {
nonLeafEvenDepthSum += node.getValue();
}
}
public void visitLeaf(TreeLeaf leaf) {
if (leaf.getColor() == Color.GREEN) {
greenLeavesSum += leaf.getValue();
}
}
}
public class Solution {
private static int [] values;
private static Color [] colors;
private static HashMap<Integer, HashSet<Integer>> map;
public static Tree solve() {
Scanner scan = new Scanner(System.in);
int numNodes = scan.nextInt();
/* Save nodes and colors */
values = new int[numNodes];
colors = new Color[numNodes];
map = new HashMap(numNodes);
for (int i = 0; i < numNodes; i++) {
values[i] = scan.nextInt();
}
for (int i = 0; i < numNodes; i++) {
colors[i] = scan.nextInt() == 0 ? Color.RED : Color.GREEN;
}
/* Save edges */
for (int i = 0; i < numNodes - 1; i++) {
int u = scan.nextInt();
int v = scan.nextInt();
/* Edges are undirected: Add 1st direction */
HashSet<Integer> uNeighbors = map.get(u);
if (uNeighbors == null) {
uNeighbors = new HashSet();
map.put(u, uNeighbors);
}
uNeighbors.add(v);
/* Edges are undirected: Add 2nd direction */
HashSet<Integer> vNeighbors = map.get(v);
if (vNeighbors == null) {
vNeighbors = new HashSet();
map.put(v, vNeighbors);
}
vNeighbors.add(u);
}
scan.close();
/* Handle 1-node tree */
if (numNodes == 1) {
return new TreeLeaf(values[0], colors[0], 0);
}
/* Create Tree */
TreeNode root = new TreeNode(values[0], colors[0], 0);
addChildren(root, 1);
return root;
}
/* Recursively adds children of a TreeNode */
private static void addChildren(TreeNode parent, Integer parentNum) {
/* Get HashSet of children and loop through them */
for (Integer treeNum : map.get(parentNum)) {
map.get(treeNum).remove(parentNum); // removes the opposite arrow direction
/* Add child */
HashSet<Integer> grandChildren = map.get(treeNum);
boolean childHasChild = (grandChildren != null && !grandChildren.isEmpty());
Tree tree;
if (childHasChild) {
tree = new TreeNode(values[treeNum - 1], colors[treeNum - 1], parent.getDepth() + 1);
} else {
tree = new TreeLeaf(values[treeNum - 1], colors[treeNum - 1], parent.getDepth() + 1);
}
parent.addChild(tree);
/* Recurse if necessary */
if (tree instanceof TreeNode) {
addChildren((TreeNode) tree, treeNum);
}
}
}