AcWing
  • 首页
  • 活动
  • 题库
  • 竞赛
  • 应用
  • 其它
    • 题解
    • 分享
    • 商店
    • 问答
  • 吐槽
  • 登录/注册

图论算法--Bellman_Ford算法和SPFA算法

作者: 作者的头像   lrx2020 ,  2023-01-24 18:52:43 ,  所有人可见 ,  阅读 37


0


Bellman_Ford算法和SPFA算法

给定一张有向图,若对与图中的某一条边(x,y,z),有dist[y] <= dist[x] + z 成立,则称该边满足三角不等式。若所有边都满足三角不等式,则dist数组就是所求最短路。
Bellman_Ford算法的基本流程:
1.扫描所有边(x,y,z),若dist[y] > dist[x] + z,则用dist[y]更新。
2.重复所有步骤,真到没有更新操作发生。
实际上,SPFA算法在国际上统称为:”队列优化版的Bellman_Ford算法”。
SPFA算法的基本流程:
1.建立一个队列,最初队列中只含有起点1。
2.取出都节点x,扫描它的所有出边(x,y,z),若dist[y] > dist[x] + z,则用dist[y]更新。同时,若y不在队列中,则把y入列。
3.重复上面步骤,直到队列为空为止。
即使图中存在长度为负的边,Bellman_Ford和SPFA算法也能够成功。

#include <iostream>
#include <queue>
#include <cstring>

using namespace std;
const int N = 1000010,M = 1000010;
int head[N],ver[N],edge[N],next[N],d[N];
int n,m,tot;
queue<int> q;
bool v[N];

void add(int x,int y,int z){
    ver[++tot] = y; edge[tot] = z; next[tot] = head[x]; head[x] = tot;
}

void spfa(){
    memset(d,0x3f,sizeof(d));
    memset(v,0,sizeof(v));
    d[1] = 0; v[1] = 1;
    q.push(1);
    while(q.size()){
        int x = q.front();
        q.pop();
        v[x] = 0;
        for(int i=head[x];i;i=next[i]){
            int y = ver[i], z = edge[i];
            if(d[y]>d[x]+z){
                d[y] = d[x] +  z;
                if(!v[y]) q.push(y),v[y] = 1;
            }
        } 
    }
}

int main(){
    cin >> n >> m;
    for(int i=1;i<=m;i++){
        int x,y,z;
        cin >>  x >> y >> z;
        add(x,y,z);
    }
    spfa();
    return 0;
} 

0 评论

你确定删除吗?
1024
x

© 2018-2023 AcWing 版权所有  |  京ICP备17053197号-1
用户协议  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标
请输入绑定的邮箱地址
请输入注册信息