Bellman-Ford算法(求单源最短路径)

struct EdgeNode{    //邻接链表节点
    int num;
    int weigh;
    EdgeNode* next;
    EdgeNode():num(0),weigh(0),next(nullptr){}
    EdgeNode(int x,int w):num(x),weigh(w),next(nullptr){}
};


//Bellman-Ford算法:O(|E|*|V|)复杂度,用来求解单源最短路径(从某个起点s到达所有其它节点的最短路径)
bool Bellman_Ford(vector<EdgeNode*>& vertexList,int s)
{
    int vertexNum=vertexList.size();    //顶点数
    vector<int> dis(vertexNum,100000); //dis[i]:s到i的最短路径,初始化为无穷大
    vector<int> pre(vertexNum,-1); //pre[i]:s到i的最短路径上i的前继节点号,初始化为-1(即NULL)
    dis[s]=0;
    for(int i=1;i<vertexNum;++i){   //循环【总顶点数-1】次,每次循环都能确定一个节点的最短路径,由于起点s不需要确定,所以是-1
        int u=0;
        for(auto node:vertexList){  //当前节点node,其顶点号为u
            if(u==s){
                ++u;
                continue;
            }
            auto n=node;
            while(n!=nullptr){  //遍历与u相接的所有边
                int v=n->num;
                if(dis[v]>dis[u]+n->weigh){ //用边u-v来松弛s-v的路径
                    dis[v]>dis[u]+n->weigh;
                    pre[v]=u;
                }
                n=n->next;
            }
            ++u;
        }
    }
    //检查从起点s开始是否有权重和为负值的环路
    int u=0;
    for(auto node:vertexList){
        if(u==s){
            ++u;
            continue;
        }
        auto n=node;
        while(n!=nullptr){
            int v=n->num;
            if(dis[v]>dis[u]+n->weigh){
                return false;
            }
            n=n->next;
        }
        ++u;
    }
    //dis[i]存储起点s到i的最短路径长度
    //pre[i]存储s到i的最短路径的前继节点。从s到i的最短路径可以从pre[i]->pre[pre[i]]->pre[pre[pre[i]]]->.....再倒置得到
    return true;
}

 代码未验证,仅供参考!

posted @ 2020-06-02 14:27  NeoZy  阅读(248)  评论(0编辑  收藏  举报