Created
October 6, 2016 14:15
-
-
Save aglee/f8249ddf4ceba8e6c5318c85adf7d90a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
""" | |
https://www.hackerrank.com/challenges/cut-the-tree | |
""" | |
class Node(object): | |
def __init__(self, weight): | |
self.weight = weight | |
self.adjacent_nodes = [] | |
self.subtree_weight = weight | |
self.is_queued = False | |
self.parent_node = None | |
# First line contains number of nodes. | |
node_count = int(raw_input()) | |
# Next line contains the node weights. | |
# Create an array of nodes with those weights. | |
nodes = list(map(lambda x: Node(int(x)), raw_input().split())) | |
# The next n-1 lines contain pairs of node indexes indicating edges. | |
# Note that these indexes are 1-based. | |
for _ in range(node_count - 1): | |
edge_indexes = list(map(lambda x: int(x), raw_input().split())) | |
node_one = nodes[edge_indexes[0] - 1] | |
node_two = nodes[edge_indexes[1] - 1] | |
node_one.adjacent_nodes.append(node_two) | |
node_two.adjacent_nodes.append(node_one) | |
# Arrange the nodes in breadth-first order. Here we designate nodes[0] | |
# as the root node of the entire tree, but since the edges of a tree are | |
# non-directed (i.e. there is no inherent parent-child relationship), | |
# we could use any other node equally well. | |
root_node_index = 0 | |
queue = [nodes[root_node_index]] | |
nodes[root_node_index].is_queued = True | |
queue_index = 0 | |
while queue_index < len(queue): | |
nd = queue[queue_index] | |
for adj in nd.adjacent_nodes: | |
if not adj.is_queued: | |
queue.append(adj) | |
adj.is_queued = True | |
adj.parent_node = nd | |
queue_index += 1 | |
# Add every node's weight to its parent's subtree_weight. | |
# Work up from the bottom of the tree. Note that every node's | |
# subtree_weight was initialized to its own weight. | |
for node in reversed(queue): | |
if node.parent_node: | |
node.parent_node.subtree_weight += node.subtree_weight | |
# Find the smallest difference between the weight of a subtree and | |
# the weight of the total tree minus that subtree. | |
total_weight = nodes[root_node_index].subtree_weight | |
best_diff = total_weight | |
for node in nodes: | |
a = node.subtree_weight | |
b = total_weight - a | |
diff = abs(a - b) | |
if diff < best_diff: | |
best_diff = diff | |
print best_diff |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment