首页 > 编程语言 >最短路算法大全(Bellman-Ford &Spfa)

最短路算法大全(Bellman-Ford &Spfa)

时间:2023-08-09 17:36:22浏览次数:47  
标签:松弛 int 算法 Bellman Ford vis Spfa 队内

Bellman-Ford算法

1、基于松弛操作的单源最短路算法,针对于有向图、
2、e[u]存u点的出边的邻点和边权,d[u]存u点到原点的距离
3、初始化,d[s] = 0,d[其他点]=INF (源点到本身的距离初始化为0到其他点的距离都初始化为无穷)
4、执行多轮操作。每轮操作都对所有边尝试一次松弛操作
5、当一轮循环中没有成功的松弛操作后,算法就停止
算法模板:
对于一组数据n个点,m条边 s是要找的原点
接下来m条内容,a,b是两个点,c是边的权值

struct edge{int v,int w;};
vector<edge> e(N);
int d[N];

bool bellmanford(int s){
    memset(d,INF,sizeof d);
    d[s] = 0;
    bool flag;//是否松弛
    for(int i=1; i<=n; i++){//n轮
        flag = false;
        for(int u = 1; u<=n; u++){//对每个点枚举出边
            if(d[u] == INF)continue;
            for(auto ed:e[u]){//枚举每个u的出边
                int v = ed.v,w = ed.w;//v来存出边的终点,w来存边权,这就是松弛操作的条件
                if(d[v] > d[u] + w){
                    d[v] = d[u] + w;
                    flag = true;
                }
            }
        }
        if(!flag)break;
    }
    return flag; //第n轮=true则有环
} 

int main()
{
    cin>>n>>m>>s;
    for(int i=0;i<m;i++)
    {
        cin>>a>>b>>c;
        e[a].push_back({b,c});
    }
}

整个过程模拟:

i指的是每一轮的循环,
i=1  u=1
     u=2
     u=3 d[1]=6 d[2]=1
     u=4
i=2  u=1 d[4]=9
     u=2 d[1]=2 d[4]=6
     u=3 
     u=4
i=3  u=1 d[4]=5
     u=2,3,4
i=4  u=1,2,3,4

     flag=false

Bellman-Ford算法可以正确的处理负边权


Bellman Ford 可以处理有负边的图

时间复杂度

没轮循环是O(m)的,如果最短路存在,一轮松弛操作会使最短路的边数至少执行+1,而最短路的边数最多为n-1最多执行n-1论松弛操作,故时间复杂度为O(nm)
如果第n轮循环时仍然存在能松弛的边,说明从s点出发,能够抵达一个负环,因此bellman-Ford算法还可以判断负环

Spfa(bellmanford的优化)

原理:只有本轮被更新的点,其出边才有可能引起下一轮的松弛操作,因此用队列来维护被更新的点的集合

vis[u]标记u点是否在队内,cnt[v]记录边数判断负环。

  • 1.初始化,原点s入队,标记s在队内d[s] = 0,d[其他点] = +无穷
  • 2.从队头弹出u点,标记u不在队内
  • 3.枚举u的所有出边,执行松弛操作。记录s走到v的边数,并判断负环。如果v不在队内就把v压入队尾,并打上标记;
  • 4.重复2,3步操作,直到队列为空
struct edge{int v,w;};
vector<edge> e[N];
int d[N],cnt[N],vis[N];
queue<int> q;

bool spfa(int s){
    memset(d,inf,szieof d);//初始化每个点的距离
    d[s]=0;//
    vis[s]=1;//原点标记他等于1等于true
    q.push(s);
    while(q.size()){
        int u=q.front();
        q.pop();
        vis[u]=0;//出队后就将其标记为false
        for(auto ed:e[u]){
            int v = ed.v,w=ed.w;
            if(d[v]>d[u]+w){
                d[v]=d[u]+w;//如果新的路径更短
                cnt[v]=cnt[u]+1;//记录从v点走到u点都经过了一条边
                if(cnt[v]>=n)return true;
                //v点被更新且不在队内,则入队
                if(!vis[v])q.push(v),vis[v]=1;
                //如果v不在队内就把v压入队尾,并打上标记
            }
        }
        
    }
    return false;
}

标签:松弛,int,算法,Bellman,Ford,vis,Spfa,队内
From: https://www.cnblogs.com/OhLonesomeMe/p/17617460.html

相关文章

  • bellman-ford算法理解
    bellman-ford算法理解从本题谈起再回归到最短路。本题为限制边数的最短路,是这个算法优势领域的题目。为什么它能解决?最外层每循坏一次,就是各点向外走一条边,内层对边的遍历是对所有边进行松弛操作,每次进行该操作时,需要用到备份数组,目的是防止连锁反应,保证每次每个点到起点的距离......
  • 最短路之 Bellman-ford 算法
    bellman-ford算法的思想:若有向图有n个点,m条边。扫描所有边,对每条边进行一次松弛(即对a,b为端点,权重为w的边,dist[b]=min(dist[a],dist[a]+w))重复此流程(最多重复n次)直到没有更新操作发生例题1bellmanford板子给你一张n个顶点m条边的有向简单图,顶点编号从1到......
  • Bellman–Ford 算法
    目录Bellman-Ford算法记号过程举例应用应用1:Leetcode787.K站中转内最便宜的航班题目分析方法一:动态规划边界条件状态转移方法二:BellmanFord算法代码实现Bellman-Ford算法贝尔曼-福特(Bellman–Ford)算法是一种基于松弛(relax)操作的最短路径算法,可以求出有负权的图的最短路径......
  • abc061d <单源最短路, spfa, 判断负环>
    D-ScoreAttack//https://atcoder.jp/contests/abc061/tasks/abc061_d//单源最短(长)路,spfa,判断负(正)环//本题是找最长的路径,实际上取个负号即可//注意,找到一个负环不能直接结束,只能进行标记cyc[]#include<iostream>#include<algorithm>#include<vect......
  • P3371 【模板】单源最短路径(弱化版)(C++_SPFA算法_链式向前星)
    题目背景本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步P4779。题目描述如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。输入格式第一行包含三个整数n,m,s,分别表示点的个数、有向边的个数、出发点的编号。接下来m行每行包含三个......
  • Stanford NLP第三课“最小编辑距离(Minimum Edit Distance)”
    一、课程介绍斯坦福大学于2012年3月在Coursera启动了在线自然语言处理课程,由NLP领域大牛DanJurafsky和ChirsManning教授授课:链接地址以下是本课程的学习笔记,以课程PPT/PDF为主,其他参考资料为辅,融入个人拓展、注解,抛砖引玉,欢迎大家在“我爱公开课”上一起探讨学习。课件汇总下载......
  • bzoj1001 [BeiJing2006]狼抓兔子(网络流dinic算法||最短路spfa)
    http://www.lydsy.com/JudgeOnline/problem.php?id=10011001:[BeiJing2006]狼抓兔子TimeLimit: 15Sec  MemoryLimit: 162MBSubmit: 24017  Solved: 6068[Submit][Status][Discuss]Description现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓......
  • ICPC2017网络赛(乌鲁木齐)H: Skiing (SPFA最长路)
    H:Skiing timelimit1000msmemorylimit131072KB iiInthiswinterholiday,Bobhasaplanforskiingatthemountainresort.ThisskiresorthasMdifferentskipathsandNdifferentflagssituatedatthoseturningpoints.Thei-thpathfromtheS-thfl......
  • Bellman-Ford算法——为什么要循环n-1次?图有n个点,又不能有回路,所以最短路径最多n-1边
    单源最短路径给定一个图,和一个源顶点src,找到从src到其它所有所有顶点的最短路径,图中可能含有负权值的边。Dijksra的算法是一个贪婪算法,时间复杂度是O(VLogV)(使用最小堆)。但是迪杰斯特拉算法在有负权值边的图中不适用,Bellman-Ford适合这样的图。在网络路由中,该算法会被用作距......
  • spfa任意两点间最短路径
    #include<iostream>#include<queue>#include<string.h>usingnamespacestd;#defineINF0x3f3f3f3f;constintN=3000;intn,m;intg[N][N],dist[N];boolst[N];queue<int>q;voidspfa(intstart){st[start]=true;dist[s......