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; }
代码未验证,仅供参考!
进击的小🐴农