圖-最短路徑問題

在網絡中,求兩個不同頂點之間的所有路徑中,邊的權值之和最小的那一條路徑

  • 這條路徑是兩點之間的最短路徑
    *第一個頂點為源點
    *最后一個頂點為終點

問題分類

  • 單源 最短路徑問題
    從固定源點出發,求其到所有其他頂點的最短路徑
    • (有向)無權圖
    • (有向)有權圖
  • 多源 最短路徑問題
    求任意兩頂點見得最短路徑

有向無權圖的單源最短路徑

按照 遞增 的順序找出給定節點到各個節點的最短路徑

Paste_Image.png
dist[S] = 0
path[]
public  UnWeight(Vertex S){
    Enqueue(S,Q);
    while(!IsEmpty(Q)){
        V = Dequeue(Q);
        for( V 的鄰接節點 W ){
            if(dist[W]!=-1){
                dist[W] = dist[V]+1;
                path[W] = V;
                Enqueue(W,Q);
            }
        }
    }
}

有權有向圖的單源最短路徑

#dijkstra算法
令 S={源點A+已經確定了最短路徑的頂點Vi}
對任一未收錄的·頂點v·,定義dist[v] = A 到 v 的最短路徑長度。
(但該路徑僅僅經過集合S中的頂點)。
若路徑是按照 @遞增 的順序生成的=>
{
  真正的最短路必須只經過集合S中的頂點。(反證法)
  每次從未收錄的頂點中選一個dist最小的收錄(貪心)。
  增加v進入S以后,可能影響另外一個未收錄節點w的dist值
    #(比如之前不可達,或是之前的到達路徑比較長==)
    # dist[w]=min(dist[v] + E<v,w>, dist[w])
    # E<v,w>表示該邊的權重
}
Paste_Image.png
#個人BB
一個富有侵略性的算法。
想象頂點就是一個城池。
占據了頂點以后,依據已經占據的城池向外擴展。
首先擴展就是離出發點最近的領土
(始終是計算出發點和其他點的距離)。

后進來的領土會不會影響舊的領土的距離呢?
@不會
為什么?
加進來的點是按距離順序添加的。

#代碼

void Dijkstra(Vertex s){
    while(1){
        V = 未收錄頂點中dist最小者;
        if(沒有V){
            return;
        }
        collected[V]=true;
        for(V 的每個鄰接點 W)
            if(collected[W] == false)
                if(dist[V] +E(v,w) < dist[W]){
                    dist[W] = dist[V] + E(v,w);
                    path[W] = V;
                }
    }
}
/*不能解決有負邊的情況*/

如果遇到負值圈,就可能會陷入一直死循環的情況。


負值圈
  • 方法1:直接掃描所有未收錄頂點 - O(|V|) 適用于稠密圖
    • T =O(|V|*|V| + E)
每個節點都要掃一遍。V個點*V
但是其實真是情況是不是,但后面掃的范圍會變小呢...因為大部分被加入到了集合collected 中了。
E 是因為要對每個新加入的點的鄰接點進行處理,所以每條邊都會處理一遍
  • 方法2:將dist存在最小堆中-O(log(V)) 適用于稀疏圖
    • 更新dist[w]的值 - O(log|V|)
    • T = O(|N|log|V| + |E|log|V|) = O(|E|log|V|)

多源最短路徑問題

#floy算法:
#個人BB

其實和dijkstra有點像。就是不斷地添加點到一個集合中。

添加進來的點,
      #已經收錄的集合到這個點的路徑
以及  #這個點到達其他點的路徑
暴露了出來。

此時,到達k的路徑,以及從k 到達別人的路徑保持不變。
改變的是其他要經過k來走最短路徑的路。

假設之后,某個點w到k的距離發生了變化,必然是因為加了新的點k1,
那么k1,自然會將 w到k的距離發生變化,而且,會把w經過 k1到達的所有點的距離都會進行改變。
(因為之前,我在擔心,k對整個距離產生變化以后,其他點的結果相當于依賴于看k的距離,但是,如果k的距離改變了,那么豈不是其他結果不準了?
其實k距離發生變化,只有可能是有k1加入導致,如果k1導致k發生變化,那么經過k的路徑,自然一定要經過k1,
因此k1自然會將所有的后面所能到達的點全部化為更新后的最短路徑。

需要多想想。)

public void floyd(){
    for(i =0;i<N ;i++){
        D[i][j] = G[i][j];
        path[i][j] = -1;
    }
    for(int k=0;k<N;k++){
        for(int i =0;i<N;i++){
            for(int j=0;j<N;j++){
                if(d[i][k]+d[k][j] < d[i][j]){
                    d[i][j] = d[i][k]+d[k][j];
                    path[i][j] = k;
                }
            }
        }
    }
}

T=O(|V||V||V|)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • -DFS(Depth First Search):深度優先搜索 訪問完一個頂點的所有鄰接點之后,會按原路返回,對應...
    Spicy_Crayfish閱讀 2,853評論 1 0
  • 3月份一個偶然的機會刷了一道算法題,當時折騰了好久,趁現在有空趕緊記錄一下。原題地址:Rust&Murderer ...
    JianlingZhou閱讀 709評論 0 0
  • 咫尺天涯路 文||與你相識 深情放你在心頭,那些溫柔體貼 早已寫進夢里,是觸手可及卻不在夢里 所有的期盼,是一場空...
    與你相識_40fa閱讀 390評論 0 5
  • 1 連續下了幾天的雨,天氣難得好了起來,微風拂面,晴空萬里。我興高采烈給阿余發消息:“阿余,周末一起逛街吧”。 “...
    Joy喬弋閱讀 424評論 2 12
  • 十二月,北方的天氣愈發寒冷,道路旁,鋪滿了枯黃的落葉,行人瑟瑟地走著,情侶們互相依偎,說笑著,打鬧著,有著不屬...
    duolaIris閱讀 179評論 0 2