Last active
August 20, 2018 09:51
-
-
Save superkiria/befecdd591c88d6a6ad779b48156f304 to your computer and use it in GitHub Desktop.
unilec118_tree
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
# динамическое программирование | |
# возьмём вершину и решим задачу отдельно при условии, что она добавлена в подмножество, и отдельно, что нет | |
# и выберем вариант, где сумма получилась максимальной | |
# так как от любой вершины будут начинаться несколько поддеревьев, то будем решать задачи для каждого поддерева | |
def task_118(edges, value): | |
def count_a_if_b_in(a, b, fl): | |
# А - для этой вершины решаем задачу | |
# B - вершина, откуда мы пришли, -1 - значит ниоткуда | |
# fl - включена ли вершина b в подмножество | |
# будем решать задачи для деревьев, начинающихся из А | |
sum_if_a_true = 0 # при условаии, что A в подмножестве | |
sum_if_a_false = 0 # при условаии, что A не в подмножестве | |
# обходим всех соседей А, но не тот лист, откуда пришли | |
for i in graph[a] - {b}: | |
# всегда делаем расчёт для соседа, с условием, что A не в подмножестве | |
sum_if_a_false += count_a_if_b_in(i, a, False) | |
# если мы в корне дерева или пришли из вершины не входящей в подмножество, то | |
# делаем для соседа расчёт, при условии, что A в подмножестве | |
if b == -1 or not fl: | |
sum_if_a_true += count_a_if_b_in(i, a, True) | |
# если это расчёт корневой вершины или мы пришли из вершины не в подмножестве | |
# то возвращаем максимум от двух результатов | |
if b == -1 or not fl: | |
return max(sum_if_a_false, sum_if_a_true + value[a]) | |
# иначе возвращаем расчёт для случая, если A не в подмножестве | |
return sum_if_a_false | |
# создаём и наполняем граф | |
graph = [set() for i in range(0, len(edges) + 1)] | |
for i in range(0, len(edges)): | |
graph[edges[i][0] - 1].add(edges[i][1] - 1) | |
graph[edges[i][1] - 1].add(edges[i][0] - 1) | |
# вызываем функцию, которая решит задачу, начиная с вершины 1 | |
return count_a_if_b_in(0, -1, True) | |
print() | |
# пример из задачи | |
edges = [(1, 2), (1, 3), (2, 4)] | |
value = [1, 1, 0, 1] | |
print(task_118(edges, value)) | |
print() | |
# 0 | |
edges = [(1, 2), (2, 3), (3, 4)] | |
value = [-1, -2, -3, -4] | |
print(task_118(edges, value)) | |
# 1 | |
edges = [(2, 1)] | |
value = [1, 0] | |
print(task_118(edges, value)) | |
# 2 | |
edges = [(2, 1)] | |
value = [1, 2] | |
print(task_118(edges, value)) | |
# 3 | |
edges = [(2, 1), (1, 3)] | |
value = [2, 1, 2] | |
print(task_118(edges, value)) | |
# 4 | |
edges = [(2, 1), (1, 3)] | |
value = [4, 1, 2] | |
print(task_118(edges, value)) | |
# 5 | |
edges = [(2, 1), (1, 3), (3, 4)] | |
value = [4, 1, 2, 1] | |
print(task_118(edges, value)) | |
# 6 | |
edges = [(1, 2), (2, 3), (1, 4), (2, 5), (3, 6)] | |
value = [1, 1, 1, 2, 2, 2] | |
print(task_118(edges, value)) | |
# 7 | |
edges = [(1, 2), (2, 3), (3, 4)] | |
value = [-1, -2, 7, -4] | |
print(task_118(edges, value)) | |
print() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment