1. 程式人生 > >演算法學習之Bellman-Ford單源最短路問題

演算法學習之Bellman-Ford單源最短路問題

一.演算法分析

這個演算法的思路還是很清晰的,該演算法以邊作為主要研究物件。

     首先我們考慮使用一個邊,這邊用鄰接表類似的形式由u[i](儲存起始點)v[i](儲存終點)w[i](儲存邊長權值)來儲存,那麼是否可以通過這條邊來使的我們的起點到這條邊的終點的距離縮短呢?如果可以的話就縮短這個距離,如果不行的話就放棄,之後依照這個思路將所有的邊都遍歷一遍,然而這樣就結束了麼?當然不行!很容易就能想到這樣很可能找不出一套有效路徑,然而我們很容易就會發現,在已經產生一套最短路徑之前每一次遍歷都至少會誕生一個點的最短路徑,那麼在用n-1次一定可以產生一套路徑的。

其實這個演算法的思路和之前的Dijkstra很相似,只是Dijkstra使用的是點來鬆弛其它點,而本演算法是實用邊來鬆弛其它點

//
//  main.cpp
//  Bellman=Ford
//
//  Created by 張嘉韜 on 16/3/14.
//  Copyright © 2016年 張嘉韜. All rights reserved.
//

#include <iostream>
#include <cstring>
using namespace std;
int const maxn=99999999;
int main(int argc, const char * argv[]) {
    freopen("/Users/zhangjiatao/Desktop/input.txt","r",stdin);
    int n,m,u[50],v[50],w[50],dis[50];
    cin>>n>>m;
    memset(dis,0,sizeof(dis));
    for(int i=2;i<=n;i++) dis[i]=maxn;
    for(int i=1;i<=m;i++)
    {
        cin>>u[i]>>v[i]>>w[i];
    }
    for(int k=1;k<=n-1;k++)
    {
        for(int i=1;i<=m;i++)
        {
            if(dis[v[i]]>dis[u[i]]+w[i])
                dis[v[i]]=dis[u[i]]+w[i];
        }
    }
    for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
    cout<<endl;
    return 0;
}