【发布时间】:2022-01-05 10:00:46
【问题描述】:
让我们有一棵树,它的边缘由价格来衡量,价格是一些整数。我们将所有边的价格总和称为树的价格。如果我们通过删除一条边来切割一棵树,它将分成两棵树。我们称之为降价的最高价格。我们的任务是找到最便宜的切割。
输出应该是一个数字,即切割的最低价格。
例子:
输入:
5
1 4 1
1 2 1
2 3 3
4 5 2
第一个数字是顶点的数量。
之后,我们有顶点数 - 1 行。
行中的前两个数字是顶点之间的连接,所以1 4 表示1 和4 是连接的。行中的最后一个数字是边的“价格”。
所以在这种情况下,输出应该是 3,因为如果我们删除 2 和 1 之间的边,我们将得到两个子树,边分别是 3 和 3(它们的价格)。
1
/ \
2 4
\3 \2
3 5
(图中/和\是边,数字是顶点,/和\旁边的数字是边的价格)
我考虑了一段时间,但不知道执行此操作的正确算法。
我写的基本程序:
number_of_vertices = int(input())
edges = []
price = []
for i in range(number_of_vertices):
u, v, c = input().split()
edges.append([int(u),int(v)])
price.append(int(c))
我想过遍历每一条边,删除它们然后计算,但我不知道如何实现。
所以我制作了一个邻居字典和一个 find_path 算法来查找两个顶点之间是否存在边:
from collections import defaultdict
def find_path(graph, start, end, path=[]):
path = path + [start]
if start == end:
return True
if start not in graph:
return False
for node in graph[start]:
if node not in path:
newpath = find_path(graph, node, end, path)
if newpath: return True
return False
number_of_vertices = int(input())
edges = []
price = []
for i in range(number_of_vertices - 1):
u, v, c = input().split()
edges.append([int(u),int(v)])
price.append(int(c))
graph = defaultdict(set)
for vertices in edges:
graph[vertices[0]].add(vertices[1])
graph[vertices[1]].add(vertices[0])
print(find_path(graph, 1, 3)) #this is just to make sure it works
print(dict(graph)) #this too
【问题讨论】:
-
你能否改写句子:“我必须找到边,如果我删除它,我计算剩余两棵树的边,较大的'价格'是最小的我可以通过切出一条边来实现。”
-
对短语进行了一些更正
-
“我想过遍历每一条边,删除它们然后计算,但我不知道如何实现。” 那将是一个好地方开始。您需要能够检测到已删除边缘的两个组件。这实际上很简单:只需从已删除边的两个节点中的每一个开始遍历图(广度优先搜索或深度优先搜索,无关紧要)。
-
“我必须找到边缘,如果我删除它,我计算剩余两棵树的边缘,较大的“价格”是我可以通过切掉一个边缘。” 没有歧义地理解这句话仍然有点困难。我假设你想最小化两棵树的最大价格,但我不完全确定。
-
那么,第 1 步:您能否实现从给定节点开始遍历图?