對求最短路徑常見演算法的簡單總結

2021-07-12 03:49:56 字數 3666 閱讀 3581

最近正好在學最短路徑,藉此機會把學到的知識總結下,一來分享給大家閱讀,二來方便以後自己查閱。

先列一下下面會總結到的求最短路徑的演算法:

1.dijkstra演算法;

2.bellman-ford演算法;

3.folyd演算法;

4.spfa演算法;

dijkstra演算法:求單源最短路徑(不帶負權重的環)

step1.初始化,dis[v0]=0,dis[i]=無窮大(i≠v0,表示不可達);

step2.從v-u中選擇使dis[i]值最小的頂點i,將i加入到u中;

step3.更新與i直接相鄰頂點的dis值(dis[j]=min)。

step4.重複step2和step3,直到u=v,停止。

#include #include #include #include #include #include using namespace std;

#define maxn 10000

const int inf=0x3f3f3f3f;

int n, m, ori;

int dis[maxn], pre[maxn];

int cost[maxn][maxn];

struct node

node(int vv, int ll):v(vv), len(ll){}

bool operator < (const node& a) const

};void dijkstra()}}

}void print_path(int pos)

printf("%d\n", ori);

}int main()

dijkstra();

for(int i = 1; i <= n; i++)

return 0;

}

bellman-ford演算法:求單源最短路徑(可帶負權重的環)

假設存在g=,源頂點為v0,u=,dis[i]記錄v0到i的最短距離,pre[i]記錄從v0到i路徑上的i前面的乙個頂點。

step1.初始化,dis[v0]=0,dis[i]=無窮大(i≠v0,表示不可達);

step2.進行迴圈,迴圈下標為從0到v-1(v等於圖中點的個數),在迴圈內部,遍歷所有的邊,進行鬆弛操作;

step3.遍歷圖中所有的邊(edge(u,v)),判斷是否存在這樣情況:d(v) > d (u) + w(u,v),存在則返回false,表示圖中存在從源點可達的權為負的迴路。

#include #include #include #include using namespace std;

#define maxn 10000

const int inf = 0x3f3f3f3f;

struct edge

;int n, m, ori;//點數、邊數、起始點

int dis[maxn], pre[maxn];

vectoredge;

bool bellman_ford()

}bool flag = true;

for(int i = 0; i < edge.size(); i++)

}return flag;

}void print_path(int start)//列印路徑

printf("%d\n", ori);

}int main()

if(bellman_ford())

}else

printf("this map has negative circle\n");

return 0;

}

folyd演算法:所有頂點對最短路徑(不帶負權重的環)

假設存在g=,dis[i][j]記錄i到j的最短距離,path[i][j]記錄從i到j路徑上j的前面的乙個頂點。

step1.將所有頂點對之間距離初始化為無窮大(dis[i][j]=無窮大),然後將輸入的i到j的距離儲存在dis[i][j]中;

step2.依次掃瞄每乙個點,並以其為基點再遍歷所有每一對頂點dis[i][j]的值,看看是否可用過該基點讓這對頂點間的距離更小。

#include #include #include #include #include #include using namespace std;

#define maxn 10000

const int inf = 0x3f3f3f3f;

int dis[maxn][maxn], path[maxn][maxn];

int n, m, ori;

void floyd()

}}void prin_path()

printf("%d\n", i);}}

}}int main()

while(m--)

floyd();

prin_path();

return 0;

}

spfa演算法:單源最短路徑(可帶負權重的環)

假設存在g=,dis[i]記錄v0到i的最短距離,pre[i]記錄從v0到i路徑上i的前面的乙個頂點;

step1.將所有頂點對之間距離初始化為無窮大(dis[i][j]=無窮大),pre[i]=i,vis[i]=0,將源點入隊;

step2.讀取隊頭頂點now,並將隊頭頂點now出隊(記得消除標記),將與點now相連的所有點next進行鬆弛操作,更新dis[next],另外,如果點next沒有在佇列中,那麼要將點next入隊(記得標記),如果已經在佇列中了,那麼就不用入隊(如果某個頂點入隊超過v次,則說明圖中有負環,直接跳出);

step3.重複step2,直到隊空為止就完成了單源最短路的求解。

#include #include #include #include #include using namespace std;

#define maxn 10000

const int inf = 0x3f3f3f3f;

struct edge

edge(int vv, int ww):v(vv), w(ww){}

};int dis[maxn], vis[maxn], pre[maxn];

int cnt[maxn];

int n, m, ori;

vectoredge[maxn];

int spfa()

dis[ori] = 0;

q.push(ori);

vis[ori]=1;

cnt[ori]++;

while(!q.empty())}}

}return 1;

}void print_path(int pos)

printf("%d\n", ori);

}int main()

if(spfa())

else

printf("this map has negative circle\n");

return 0;

}

dijkstra演算法參考:

bellman-ford演算法參考:

folyd演算法參考:

spfa演算法參考:

最短路 求最長最短路,求最短路的路徑

hdu 1595 find the longest of the shortest include include include include include include include include include include include include include defi...

Dijkstra演算法求最短路徑

參考文獻 dijkstra一般的表述通常有兩種方式,一種用永久和臨時標號方式,一種是用open,close表方式,drew為了和下面要介紹的 a 演算法和 d 演算法表述一致,這裡均採用open,close表的方式。大概過程 建立兩個表,open,close。open表儲存所有已生成而未考察的節點,...

Dijkstra演算法求最短路徑

dijkstra演算法用來求最短距離 已經實現了 那麼最短路徑 如何求解並列印出來呢?此處的方法是記錄路徑中結點的前驅 if v未被訪問 以u為中介點可以使起點s到頂點v的最短距離d v 更優 程式具體實現,鄰接矩陣版 n為頂點數,maxv為最大頂點數 int n,g maxv maxv 起點到達各...