算法总结:
①Dijkstra算法用的是贪心策略,每次都找当前最短路径的下一个最短距离点。所以不适合带有负权的情况。至于时间效率通过各种优化可以到达不同的程度。但是朴素的Dijkstra算法永远是最稳定的。
②Bellman-Ford算法是Dijkstra的一种变式,它摒弃了贪心的策略,但是每次都需要松弛所有的路径,所以也适合负权的情况。但是时间效率较低。有资料显示,Bellman-Ford算法也可以应用贪心策略,这属于高级技巧,这里不予考虑。
③Floyd算法用的是动态规划的思想,由于是不定源点,所以它需要对所有的情况进行松弛操作,最终获得所有的最短路径长度。由于需要遍历,所以它的时间效率比较低。但是遍历策略好的话,还是能很快得到想要的结果。
④SPFA算法是用FIFO队列优化的Bellman-Ford算法,所以支持负权的情况,由于已经将需要考虑的节点放入队列中,所以避免了很多不必要的松弛,时间效率也相对较高。由于队列中无法进行修改,所以时间效率相对不稳定。
⑤所有的队列优化其实都能转化为hash优化,这里不再考虑更进一步的优化。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
一、Dijkstra算法:单源到所有节点的最短路算法。
算法要求:可以是无向图或有向图,所有边权均为正,最短路存在。如果图是五环图,则最长路也一定存在,但是如果是有环图,则最长路不一定存在。
算法思想:每次比较所有的从源点可以到达的路的长度,然后选出最短的一条放入源点集合,然后更新最短路径长度。这样,当所有的点都在源点集合中时,得到的长度就是最短路长度。
(1)使用邻接矩阵的稠密图普通Dijkstra算法
算法时间复杂度:O(n^2)
算法代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define INF (1<<31)-1 //int最大值
#define MAXN 100 //最大节点数
int dist[MAXN],c[MAXN][MAXN];
//dist[i]存放从源点到i节点的最短距离,c数组用来表示图
int n,line; //n为节点数,line为边数
//迪杰斯特拉算法主算法模块
void Dijkstra(int v) //v代表源点
{
inti,j,temp,u; //temp用于暂时存放最短路径长度
boolvis[MAXN]; //判定重复标记数组
for(i=0; i<n; i++) //dist数组与vis数组的初始化
{
dist[i]=c[v][i];
vis[i]=0;
}
dist[v]=0; //源点到源点的距离设为0
vis[v]=1; //源点默认为已经访问
for(i=0; i<n; i++) //总共应该遍历n次
{
temp=INF; //初始化temp为最大值
u=v; //初始化最短节点为当前节点
for(j=0; j<n; j++)if((!vis[j])&&dist[j]<temp)
{
u=j; //找出v距离最短的节点u
temp=dist[j]; //更新最短距离
}
if(temp==INF)return; //不存在其它节点了,返回
vis[u]=1; //标记该最短节点为已经访问
for(j=0; j<n; j++)if((!vis[j])&&dist[u]+c[u][v]<dist[j]) //松弛操作
dist[j]=dist[u]+c[u][v]; //更新最短距离
}
}
int main()
{
int p,q,len,i,j,origin;
while(scanf(“%d%d”,&n,&line))
{
if(!n&&!line) break; //如果图为空白图,则结束
for(i=0; i<n; i++)
for(j=0; j<n; j++)
c[i][j]=INF; //初始化节点间距离,默认为节点间全部不连通
while(line--) //输入这line条边的内容
{
scanf(“%d%d%d”,&p,&q,&len);
//p为边的起点,q为边的终点,len为边的长度
//下面是无向图的输入方式
if(len<c[p][q])
{
c[p][q]=len;
c[q][p]=len;
}
/*下面是有向图的输入方式
if(len<c[p][q])
c[p][q]=lem;