【アルゴリズム学習】最短経路を見つけるベルマン・フォードアルゴリズム

OAOダイクストラアルゴリズムは複雑さの点で優れていますが、その最大の欠点は、負の加重グラフを処理できないことです。

(更新されたソースポイントからのエッジが最短パスに到達している必要があるという事実に基づいているため、最短パスを見つけるために貪欲な戦略が採用されます

負の電力経路がある場合、この基盤は確立されません。

 

現時点では、Bellman-Fordアルゴリズムが招待されます

(正当性の証明:https://oi-wiki.org/graph/shortest-path/)

コードemmを投稿:

#include <bits / stdc ++。h>
 using  namespace std;

// Bellman-Fordキューの最適化
const  int maxn = 1e5 + 5 ;

struct edge {
     int to、w;
};

bool book [maxn];
int dis [maxn];
キュー < int > q;
ベクトル <edge> Edges [maxn];
int n、m、s;
int u、v、w;

int main(){
    cin >> n >> m >> s;
    while(m-- ){
        scanf(" %d%d%d "、&​​u、&v、&w);
        edge [u] .push_back(edge {v、w});
    }
    フィル(DIS、DIS + N + 10x3f3f3f3f )。
    dis [s] = 0 ;

    本[s] = 1 ;
    q.push(s);
    while(!q.empty()){
         int t = q.front();
        
        q.pop();
        forint i = 0 ; i <edge [t] .size(); i ++ ){
             if(dis [edges [t] [i] .to]> dis [t] + Edges [t] [i] .w ){
                dis [edges [t] [i] .to] = dis [t] + edge [t] [i] .w;
                if(!book [edges [t] [i] .to]){
                    book [edges [t] [i] .to] = 1 ;
                    q.push(edges [t] [i] .to);
                }
            }
        }
        book [t] = 0 ;
    }

    forint i = 1 ; i <= n; i ++ 
        cout << dis [i] << "  " ;
    0を返し ます
}

キュー内の各ポイントについて、すべての出力エッジに対応するエンドポイントからソースポイントまでの距離を更新します

更新されたパスのポイントをキューに入れます

キューに追加できるポイントがなくなるまで(つまり、すべてのポイントがソースポイントに最も近い)

その場合、ベルマンフォードのキューの最適化(つまり、SPFA)は不安定な最適化であり、最悪はベルマンフォードのO(NM)に低下します。

(Emmは、特別に構成されたデータがSPFAカードをTに取得できることを意味します。したがって、負の重みがない場合は、ダイクストラを呼び出すことをお勧めします)

おすすめ

転載: www.cnblogs.com/leafsblogowo/p/12700316.html