最短路
Floyed——弗洛伊德 O(N^3)
最简单的算法
适用于出现负边权的情况
for(int k=1;k<=n;k++) //中间点k
for(int i=1;i<=n;i++) //起点i
for(int j=1;j<=n;j++) //终点j
if(dis[i][j]>dis[i][k]+dis[k][j])
dis[i][j] = dis[i][k]+dis[k][j];
dijkstra O(n^2)
只能计算起点只有一个的情况
不能处理负边权
设起点为s,终点为e
dis[v] 表示从s到v的最短路径
for(int i=1;i<=n;i++) c[i] = g[[s][i];
b[s] = true;
c[s] = 0;
for(int i=1;i<n;i++)
{
minn = 1e30;
k = 0;
for(int j=1;j<=n;j++)
{
if( (!b[j]) && (c[j]<minn)
{
minn = c[j];
k = j;
}
}
if(k==0) break;
b[k] = true;
for(int j=1;j<=n;j++)
{
if( c[k]+g[k][j]<c[j] )
c[j] = c[k]+g[k][j];
}
}
Bellman-Ford O(NE)
能处理负边权
无法处理存在负边回路的情况
s为起点,e为终点
n:顶点数
E:边数
dis[v]:s到v的最短距离
pre[v]:v的前驱
w[j]:边 j 的长度,且 j 连接 u,v
初始化:dis[s] = 0,dis[v] = +∞,pre[s] = 0
for(int i=1;i<n;i++)
for(int j=1;j<=E;j++)
if(dis[u]+w[j]<dis[v])
{
dis[v] = dis[u]+w[j];
pre[v] = u;
}
SPFA O(kE)
Bellman-Ford 的队列实现
dis[i]: 起点s到 i 的最短路径
w[i][j]:连接 i, j 边的长度
pre[v]:v的前驱
a[i] :队列
b[i]:(bool)记录点 i 是否在队列中
初始化:1)dis[s] = 0 ,2)dis[v] = +∞,3)memset(b,false,sizeof(b));
while(head<tail)
{
head++;
t = a[head];
b[t] = true;
for 与u相连的所有点v //用数组模拟邻接表存储
if(dis[v]>dis[u]+w[u][v])
{
dis[v] = dis[u]+w[u][v];
pre[v] = u;
if(!b[v])
{
tail++;
b[v] = true;
}
}
}