• 最短路的另外两种算法


    //由于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要注意
  • 相关阅读:
    MS SQL Server迁移至Azure SQL
    Aras Innovator 11 sp2 firefox客户端设置
    Aras Innovator 11 sp2 IE客户端设置
    Aras Innovator 11 sp2安装
    JDK Windows安装
    mocha测试es6问题
    jQuery中animate与scrollTop、offset().top实例
    AI下载步骤
    Visual Studio Code必备插件
    Visual Studio code快捷键
  • 原文地址:https://www.cnblogs.com/rainyskywx/p/9960537.html
Copyright © 2020-2023  润新知