Bellman-Ford算法

1、时间复杂度:O(V*E);  V--->顶点数、E--->边数

2、优点:可以处理负权值的情况,实现简单

3、最多进行V-1次松弛,因为要对所有的点进行遍历松弛,起点可以除外

4、主要用于存在负权值的图中(没有也可以,只是效率低);也可以判断图中是否存在环(在进行了V-1次遍历松弛后,再进行一次遍历,若最短路还能更新,则证明有环)

//对每个顶点进行松弛(即遍历求最短路),除起点外共需进行V-1次
//此代码为无向图(有向图只需把初始化e的那几条语句改动一下就好,即去掉一个方向)
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
const int NUM = 1005;

struct Node
{
    /* data */
    int u,v,wei;//起点、终点、边权
};

int flag = 0;
vector<Node> e;
//int edge[NUM][NUM];//edge[i][j]:边i->j的权值
int dis[NUM];//dis[i]:从起点到顶点i的最短路径
int V,E;//顶点个数;边数

void bf(int st)//st:起点
{
    memset(dis,0x3f3f,sizeof dis);
    dis[st] = 0;//起点到其本身为0
    //开始松弛
    for(int i=1;i<=V-1;i++)
    {
        for(int j=0;j<e.size();j++)
        {
            int u=e[j].u, v=e[j].v, w=e[j].wei;
            if(dis[v] >dis[u]+w)
                dis[v] = dis[u]+w;
        }
    }

    for(int i=0;i<e.size();i++)
    {
        int u=e[i].u, v=e[i].v, w=e[i].wei;
        if(dis[v] >dis[u]+w)
        {
            dis[v] = dis[u]+w;
            flag = 1;//还有更新说明有环
        }    
    }
}

int main()
{
    cin >> V >> E;
    int u,v,w;
    for(int i=0;i<E;i++)
    {
        cin >> u >> v >> w;
        e.push_back({u,v,w});
        e.push_back({v,u,w});
        //edge[u][v] = w;
        //edge[v][u] = w;
    }
    bf(1);
    int n;//假设到顶点n,也可以通过键盘输入
    n = V;//假设顶点按照序号来
    if(flag) cout<<"No the shortest route"<<endl;
    else cout<<dis[n]<<endl;//从1 到 n 的最短路
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值