最短路径

最短路

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;
	       }
	   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值