2014-12-21 85 views
-1

圖G是一個無向圖,其所有邊的權重相同。 u,v是2給定的頂點,如何找到O(| V |)中圖G中u和v之間最短路徑的個數?如何查找無向圖中兩個給定頂點之間的所有最短路徑?

| V |代表G中頂點的數量。

+0

我不認爲這是可以做到的。 'O(| V |)'太嚴格了。 BFS(我假設它是答案的基礎)需要'O(| E | + | V |)',並且需要O(| E | + | V |)來正確讀取圖形。 – amit

+0

[查找未加權無向圖中兩個節點之間的所有最短路徑]的可能副本(http://stackoverflow.com/questions/14144071/finding-all-the-shortest-paths-between-two-nodes-in-unweighted -directed圖) – aerokite

+0

@AerofoilKite鏈接的問題要求*找到*所有最短路徑。這隻要求*計數*它們。這是更容易的任務。 – amit

回答

4

您可以使用BFS的計數變化。

這個想法是保存一個字典,它映射dict:(v,depth)->#paths(入口是頂點和當前深度,值是從源到具有所需深度的該頂點的路徑數)。

在BFS的每次迭代中,您都會跟蹤路徑的當前深度,並將找到的路徑的數量添加到下一級別。

,如果有3條路徑導致x和4點的路徑,導致y,無論在深度3,並且兩者都具有邊緣(x,u),(y,u)想法 - 然後有7條路徑導致u - 3導致x +(X ,u)和4導致y +(y,u)。

看起來應該是這樣的:

findNumPaths(s,t): 
    dict = {} //empty dictionary 
    dict[(s,0)] = 1 //empty path 
    queue <- new Queue() 
    queue.add((s,0)) 
    lastDepth = -1 
    while (!queue.isEmpty()) 
     (v,depth) = queue.pop() 
     if depth > lastDepth && (t,lastDepth) is in dict: //found all shortest paths 
      break 
     for each edge (v,u): 
      if (u,depth+1) is not entry in dict: 
       dict[(u,depth+1)] = 0 
       queue.push((u,depth+1)) //add u with depth+1 only once, no need for more! 
      dict[(u,depth+1)] = dict[(u,depth+1)] + dict[v,depth] 

     lastDepth = depth 
    return dic[t] 

運行時,如果使用哈希表詞典O(V + E)。


另一種解決方案(更容易編程但效率較低)爲:

1. Build the adjacency matrix of the graph, let it be `A`. 
2. Set `Curr = I` (identity matrix) 
3. while Curr[s][t] != 0: 
    3.1. Calculate Curr = Curr * A //matrix multiplication 
4. Return Curr[s][t] 

它工作的原因是(A^n)[x][y]是大小n的路徑在圖中A表示從xy數。我們找到第一個高於零的數字,然後返回路徑的數量。

+0

第二種解決方案很聰明,但運行時間不能是O(V + E)。 – Gary33

+0

@ Gary33不,第二種解決方案效率較低 - 但它在Matlab中編程優雅,美觀並且非常容易,因此我決定添加它。第一個應該符合你的複雜性要求,但是編程更難。 – amit

+0

感謝您的幫助! – Gary33

相關問題