zoukankan      html  css  js  c++  java
  • bellman-ford算法求K短路O(n*m),以及判负环O(n*m)

    132
    321

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    
    const int N=510,M=1e4+10;
    
    int n,m,k,dis[N],backup[N];
    //dis数组表示dis[i]到起点的距离。
    
    struct 
    {
        int a,b,w;
    }edge[M];
    
    //bellman-ford可以求出来图中有没有负权回路。
    
    //迭代k次返回的数表示:从起点经过不超过k条边到各个点的最短距离
    
    /*
    bellman-ford可以判断负环O(n*m),如果第n次迭代仍然有更新,则说明找到
    了n条边的最短路径,如果一条最短路径上有n条边,
    即有n+1个点,根据抽屉原理,说明有负环。
    
    一般用spfa算法判断负环
    */
    int bellman_ford()//直接返回k短路的距离,当k==m时返回起点到终点的最短距离
    {
        memset(dis,0x3f,sizeof dis);
        dis[1]=0;
        
        for(int i=0;i<k;i++)//k次迭代,没次迭代每次得到一个
        //到起点的最近的邻居点。
        {
            //防止出现串联的情况
            memcpy(backup,dis,sizeof dis);
            for(int j=0;j<m;j++)//枚举所有的m条边
            {
                int a=edge[j].a,b=edge[j].b,w=edge[j].w;
                dis[b]=min(dis[b],backup[a]+w);
            }
        }
        
        if(dis[n]>0x3f3f3f3f/2)return -1;
            return dis[n];
        
    }
    
    int main()
    {
        cin>>n>>m>>k;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].w);
        }
        int t=bellman_ford();
        if(t==-1)
        cout<<"impossible";
        else
        cout<<t;
        return 0;
    }
    
  • 相关阅读:
    linux 查看安装软件位置(持续跟新)
    POJ 3661 Running (DP思想)
    stringstream的用法
    关于实验室搬家
    POJ 搜索(2)
    Treap的插入删除实现
    碰到一道不错的扩展欧几里德题目 whu 1338
    SRM 144
    关于无向图双连通问题
    POJ 动态规划(2)
  • 原文地址:https://www.cnblogs.com/forward-985/p/13697316.html
Copyright © 2011-2022 走看看