最短路的另外两种算法

//由于Dijksrta算法,当图中的权值边含有负值时,求不出最短路
//原因是因为,每个结点只能入队一次,被访问过后永久标记,所以,当存在一条负的权值边
//使得某一个节点到源点s的距离更短时,无法再一次调用此结点更新其余的点
//所以下面介绍另外的两种算法
//Bellman-Ford算法:如果存在一条最短路,一定不存在环
//如果有环,则环程序会在环中循环,无法跑出来,如果存在最短路,一定没有负环 
//因为一直在负环当中跑,最短路的路径会一直减小,没有一个最小值
//下面先上代码:(有一些地方还没明白,只能先盲敲一遍了)
bool bellman ford(int s)
{
    queue<int> Q;
    memset(inq,0,sizeof(inq));//inq数组记录结点有没有被访问过
    memset(cnt,0;sizeof(cnt));//cnt数组记录每一个结点出现的次数,由于负边的存在,一个结点可被访问多次
                              //如果某一个结点被访问的次数大于n,则一定说明一定含有环
    for(int i=0;i<n;i++) 
    d[i]=inf;
    d[s]=0;
    inq[s]=true;
    Q.push(s);
    while(!Q.empty())
    {
        int u=Q.front();
              Q.pop();
              inq[u]=false;
              for(int i=0;i<G.size();i++)
              Edge& e=edges[G[u][i]];
              if(d[u]<inf&&d[e.to]>d[u]+e.dist)
              {
              d[e.to]=d[u]+e.dist;
              p[e.to]=G[u][i];
              if(!inq[e.to])
              {
                  Q.push(e.to)
                  inq[e.to]=true;
                  if(++cnt[e.to]>n)
                  return false;
              }
             }          
    }
    return true;    
 } 
//Floy算法时间复杂度O(n*n*n),基于动态规划
for(int k=0;k<n;k++)
for(int i=;i<n;i++)
for(int j=0;j<n;j++)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
//如果不关心路径的长度,而只要路径是否连通
//则代码改写成d[i][j]=d[i][j]||(d[i][k]&&d[k][j])
//初始化时,初始化d[i][j]为inf要注意
原文地址:https://www.cnblogs.com/rainyskywx/p/9960537.html