最短路径问题是图论中很重要的问题。
解决最短路径几个经典的算法
1、Dijkstra算法
单源最短路径(贪心),还有用 priority_queue 进行优化的 Dijkstra 算法。
2、bellman-ford算法
允许负权边的单源最短路径算法
优点:可以发现负圈。缺点,时间复杂度比Dijkstra算法高。
算法流程:
(1)初始化:将除源点外的所有顶点的最短距离估计值d[v]趋于正无穷,d[start]=0
(2)迭代求解:反复对边集E中的每条边进行松弛操作,使得顶点V中的每个顶点v的最短距离估计值逐步逼近其最短距离(运行|v|-1次)
(3)检验负权回路:判断边集E中的每一条边的两个顶点是否收敛。如果存在未收敛的顶点,则算法返回false,表明问题无解,否则算法返回true,并从源点可达的顶点v的最短距离保存在d[v]中。
Bellman-Ford(G,w,s) :boolean //图G ,边集 函数 w ,s为源点
1 for each vertex v ∈ V(G) do //初始化 1阶段
2 d[v] ←+∞
3 d[s] ←0; //1阶段结束
4 for i=1 to |v|-1 do //2阶段开始,双重循环。
5 for each edge(u,v) ∈E(G) do //边集数组要用到,穷举每条边。
6 If d[v]> d[u]+ w(u,v) then //松弛判断
7 d[v]=d[u]+w(u,v) //松弛操作 2阶段结束
8 for each edge(u,v) ∈E(G) do
9 If d[v]> d[u]+ w(u,v) then
10 Exit false
11 Exit true
3、SPFA
是bellman-ford + 队列优化,其实和bfs关系更密
4、floyd算法
多元最短路算法,是一个经典的动态规划算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544
题目大意是:已知顶点数n,边数及权值,求第1个点到第n个点的最短路的长度
有很多种解法
1、Dijkstra
推荐博客:【算法】【ACM】深入理解Dijkstra算法(单源最短路径算法)
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int INF = 9999999;
int map[105][105];
int d[105];
bool vis[105];
int N,M;
void dijkstra()
{
int i,j,min,pos;
for(i=1;i<N;i++)
{
min = INF;
for(j=1;j<=N;j++)
{
if(!vis[j] && d[j]<min)
{
min = d[j];
pos = j;
}
}
if(min == INF)
return ;
vis[pos] = true;
for(j=1;j<=N;j++)
{
if(!vis[j] &