【问题标题】:Counting transversal paths in a graph计算图中的横向路径
【发布时间】:2023-01-30 03:16:49
【问题描述】:

给定一棵有 n 个顶点的树,每个顶点都有一个特殊的值 C_v。长度 k >= 1 的直线路径被定义为顶点序列 v_1, v_2, ..., v_k 使得序列的每两个连续元素由一条边连接并且所有顶点 v_i 都不同。直线路径可能不包含任何边缘。换句话说,对于 k = 1,包含单个顶点的序列也是一条直线路径。定义了一个函数 S。对于给定的直线路径 v_1, v_2, ... , v_k 我们得到 S(v_1, v_2, ... ,v_k) = Cv_1 - Cv_2 + Cv_3 - Cv_4 + ... 计算树中所有直线路径的函数 S 值的总和。由于结果可能非常大,请给出除以 10^9 + 7 后的余数。 路径按指示处理。例如:路径 1 -> 2 -> 4 和 4 -> 2 -> 1 被视为两条不同的路径,并且对于每条路径,应在结果中分别考虑函数 S 的值。

我的实现如下:

def S(path):
    total, negative_one_pow = 0, 1
    for node in path:
        total += (values[node - 1] * negative_one_pow)
        negative_one_pow *= -1
    return total


def search(graph):
    global total
    for node in range(1, n + 1):
        queue = [(node, [node])]
        visited = set()
        while queue:
            current_node, path = queue.pop(0)
            if current_node in visited:
                continue
            visited.add(current_node)
            total += S(path)
            for neighbor in graph[current_node]:
                queue.append((neighbor, [*path, neighbor]))


n = int(input())
values = list(map(int, input().split()))
graph = {i: [] for i in range(1, n + 1)}
total = 0

for i in range(n - 1):
    a, b = map(int, input().split())
    graph[a].append(b)
    graph[b].append(a)

search(graph)
print(total % 1000000007)

对于更大的图,代码的执行时间太长。你能建议加速代码的方法吗?

【问题讨论】:

    标签: algorithm graph tree dynamic-programming graph-theory


    【解决方案1】:

    它是一棵树。因此,所有直线路径都从某个地方开始,向上行进一段距离(可能为 0),达到峰值,然后掉头向下一段距离(可能为 0)。

    首先为每个节点计算上升到其子节点的所有奇数长度路径的总和和计数,以及上升到其子节点的所有偶数长度路径的总和和计数。这可以通过动态规划来完成。

    有了它,我们可以为每个节点计算以该节点为峰值的所有路径的总和。 (计算上升到峰值然后下降的所有路径的总和。对于每个孩子,减去上升到那个孩子然后又回到那个孩子的所有路径的总和。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-29
      • 2011-10-22
      • 2011-07-30
      相关资源
      最近更新 更多