簡體   English   中英

計算圖中的橫向路徑

[英]Counting transversal paths in a graph

給定一棵有 n 個頂點的樹,每個頂點都有一個特殊的值 C_v。 長度 k >= 1 的直線路徑被定義為頂點序列 v_1, v_2, ..., v_k 使得序列的每兩個連續元素由一條邊連接並且所有頂點 v_i 都不同。 直線路徑可能不包含任何邊緣。 換句話說,對於 k = 1,包含單個頂點的序列也是一條直線路徑。 定義了一個 function S。 對於給定的直線路徑 v_1, v_2, ... , v_k 我們得到 S(v_1, v_2, ... ,v_k) = Cv_1 - Cv_2 + Cv_3 - Cv_4 +... 計算 function S 的值之和對於樹中的所有直線路徑。 由於結果可能非常大,請給出除以 10^9 + 7 后的余數。路徑按定向處理。 例如:路徑 1 -> 2 -> 4 和 4 -> 2 -> 1 被視為兩個不同的路徑,並且對於每個路徑,結果中應分別考慮 function 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)

對於更大的圖,代碼的執行時間太長。 你能建議加速代碼的方法嗎?

它是一棵樹。 因此,所有直線路徑都從某個地方開始,向上行進一段距離(可能為 0),達到頂峰,然后掉頭並 go 向下一段距離(可能為 0)。

首先為每個節點計算上升到其子節點的所有奇數長度路徑的總和和計數,以及上升到其子節點的所有偶數長度路徑的總和和計數。 這可以通過動態規划來完成。

有了它,我們可以為每個節點計算以該節點為峰值的所有路徑的總和。 (計算上升到峰值然后下降的所有路徑的總和。對於每個孩子,減去上升到那個孩子然后又回到那個孩子的所有路徑的總和。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM