import sys
class Node():
def __init__(self, _id) -> None:
self.id = _id
self.subnodes = []
self.sub_paths = []
self.path_value = 0
self.father = -1
def __str__(self) -> str:
str1 = ""
for k, i in zip(self.subnodes, self.sub_paths):
str1 += f"[{self.id} to {k}: len {i}] "
return f"\\{str1}\\"
def __repr__(self) -> str:
return self.__str__()
i = 0
m = 0
n = 0
G = []
def solve(limit, rootid):
def get_len_set(node_id) -> set:
out = {0}
chiled_sets = []
# 叶子节点直接退出
if len(G[node_id].subnodes) < 1:
return out
# 把每个子节点的可能性集合先计算并 cache
for i, v in zip(G[node_id].subnodes, G[node_id].sub_paths):
# 得到子节点以下的所有可能性
set_sub = get_len_set(i)
sub_result = {0}
# 给这些可能性加上走向这个节点的消耗
for j in set_sub:
result_sub = v + j
if result_sub <= limit:
sub_result.add(result_sub)
# 把可能性集合按照子节点顺序存储在列表中
chiled_sets.append(sub_result)
# 走一条路的情况
for i in chiled_sets:
out = out.union(i)
# 走两条路情况
if len(chiled_sets) > 1:
for k, i in enumerate(chiled_sets[:-1]):
for j in chiled_sets[k+1:]:
bi_result = {0}
for ii in i:
for jj in j:
if ii + jj <= limit:
bi_result.add(ii+jj)
out = out.union(bi_result)
return out
return max(get_len_set(rootid))
for line in sys.stdin:
if i == 0:
m = int(line)
if i == 1:
n = int(line)
G = [Node(i) for i in range(n)]
if i >= 2:
node_id, target_id, value = line.strip().split()
node_id = int(node_id)
target_id = int(target_id)
value =int(value)
# if node_id > target_id:
# tmp = node_id
# node_id = target_id
# target_id = tmp
if target_id not in G[node_id].subnodes:
G[node_id].subnodes.append(target_id)
G[node_id].sub_paths.append(value)
G[target_id].path_value = value
G[target_id].father = node_id
i += 1
if i > 2 and i >= n+1:
# solve(m, n, G)
# print(G)
root = 0
for i in G:
if i.father == -1:
root = i.id
print(solve(m, root))
i = 0
m = 0
n = 0
G = []
使用深度优先搜索,思路是构建一个函数,获取某个节点所包含的所有走法到代价,在构建代价集合的时候就可以去掉超出限制的代价路径,比较坑的是如何去建这个树的过程。python中的集合可以非常省力。

京公网安备 11010502036488号