简介:

给定一个图和一个源点,求源点到其余点的最短路径,图中有可能存在负权边。

算法步骤

1.初始化:将除源点外的所有顶点的最短距离估计值 dist[v] ← +∞, dist[s] ←0; 
2.迭代求解:反复对边集E中的每条边进行松弛操作,使得顶点集V中的每个顶点v的最短距离估计值逐步逼近其最短距离;(运行|v|-1次) 
3.检验负权回路:判断边集E中的每一条边的两个端点是否收敛。如果存在未收敛的顶点,则算法返回false,表明问题无解;否则算法返回true,并且从源点可达的顶点v的最短距离保存在 dist[v]中。

如果存在从源点可达的权为负的回路。则 应为无法收敛而导致不能求出最短路径。

经过第一次遍历后,点B的值变为5,点C的值变为8,这时,注意权重为-10的边,这条边的存在,导致点A的值变为-2。(8+ -10=-2)

第二次遍历后,点B的值变为3,点C变为6,点A变为-4。正是因为有一条负边在回路中,导致每次遍历后,各个点的值不断变小。所以这是无限循环的。

#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 0x3f3f3f3f
#define N 1010
int nodenum, edgenum, original; //点,边,起点
typedef struct Edge //边
{
    int u, v;
    int cost;
} Edge;
Edge edge[N];
int dis[N], pre[N];
bool Bellman_Ford()
{
    int ok;
    ; i <= nodenum; ++i) //初始化,起点本身赋值为0,其余赋值为最大
        dis[i] = (i == original ?  : MAX);
    ; i <= nodenum - ; ++i)
    {
        ok=;
        ; j <= edgenum; ++j)
            if(dis[edge[j].v] > dis[edge[j].u] + edge[j].cost) //松弛(顺序一定不能反)
            {
                dis[edge[j].v] = dis[edge[j].u] + edge[j].cost;
                pre[edge[j].v] = edge[j].u;//这里用来存储路径
                ok=;
            }
        ) //优化这里,如果这趟没跟新任何节点就可以直接退出了。
            break;
    }
    ; //判断是否含有负权回路
    ; i <= edgenum; ++i)
        if(dis[edge[i].v] > dis[edge[i].u] + edge[i].cost)
        {
            flag = ;
            break;
        }
    return flag;
}
void print_path(int root) //打印最短路的路径(反向)
{
    while(root != pre[root]) //前驱
    {
        printf("%d-->", root);
        root = pre[root];
    }
    if(root == pre[root])
        printf("%d\n", root);
}

int main()
{
    scanf("%d%d%d", &nodenum, &edgenum, &original);//输入点边起点,一般起点规定为1
    pre[original] = original;//为了输出最短路用的,前驱为本身
    ; i <= edgenum; ++i)
    {
        scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].cost);//有向图
    }
    if(Bellman_Ford())//如果没有负权
        ; i <= nodenum; ++i) //每个点最短路
        {
            printf("%d\n", dis[i]);
            printf("Path:");
            print_path(i);
        }
    else
        printf("have negative circle\n");
    ;
}

最短路-Bellmanford的更多相关文章

  1. 训练指南 UVA - 11478(最短路BellmanFord+ 二分+ 差分约束)

    layout: post title: 训练指南 UVA - 11478(最短路BellmanFord+ 二分+ 差分约束) author: "luowentaoaa" catal ...

  2. 训练指南 UVA - 11090(最短路BellmanFord+ 二分判负环)

    layout: post title: 训练指南 UVA - 11090(最短路BellmanFord+ 二分判负环) author: "luowentaoaa" catalog: ...

  3. 单源最短路——Bellman-Ford算法

    1.Dijkstra的局限性 Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的. 列如以 ...

  4. (模板)hdoj2544(最短路--bellman-ford算法&&spfa算法)

    题目链接:https://vjudge.net/problem/HDU-2544 题意:给n个点,m条边,求点1到点n的最短路. 思路: 今天学了下bellman_ford,抄抄模板.dijkstra ...

  5. SPFA求最短路——Bellman-Ford算法的优化

    SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环.SPFA 最坏情况下复杂度和朴素 Bellman-Ford 相同,为 O(VE), ...

  6. 图论:最短路-Bellman-Ford

    我们之前介绍了一种,(最常用的)SPFA算法,SPFA算法是对Bellman-Ford算法的队列优化,用队列替代了Bellman-Ford中的循环检查部分 然后这里我们介绍Bellman-Ford算法 ...

  7. 最短路--Bellman-Ford

    Bellman-Ford 贝尔曼-福特 算法思想 贝尔曼-福特算法(英语:Bellman–Ford algorithm),求解单源最短路径问题的一种算法,由理查德·贝尔曼 和 莱斯特·福特 创立的.它 ...

  8. 单源最短路 Bellman-Ford算法(有向图)

    // 单源最短路问题 // Bellman-Ford算法 // 复杂度O(V*E) //! 可以判断负圈 #include <cstdio> #include <iostream&g ...

  9. POJ-3259(最短路+Bellman-Ford算法判负圈)

    Wormholes POJ-3259 这题是最短路问题中判断是否存在负圈的模板题. 判断负圈的一个关键就是理解:如果在图中不存在从s可达的负圈,最短路径不会经过一个顶点两次.while循环最多执行v- ...

随机推荐

  1. redis 查看所有键值

    zb@zb-computer:/home/wwwroot/default/lion/Admin$ /usr/local/redis/bin/redis-cli 127.0.0.1:6379> k ...

  2. shell脚本实现轮询查看进程是否结束

    功能需求: 一个shell脚本,为了使用多进程,启动十几个后台运行的程序,为了防止脚本比后台进程提前结束造成不可预估的影响,现要判断是否多个后台执行的已知进程已经结束,并在所有进程结束后做出相应操作. ...

  3. btrace 常见问题

    执行btrace命令报错:Unable to open socket file: target process not responding or HotSpot VM not loaded ---- ...

  4. 如何设计一个优雅健壮的Android WebView?(下)

    转:如何设计一个优雅健壮的Android WebView?(下) 前言 在上文<如何设计一个优雅健壮的Android WebView?(上)>中,笔者分析了国内WebView的现状,以及在 ...

  5. PHP 练习1:新闻发布

    1.新闻发布主页面 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://w ...

  6. MongoDB安装配置及使用

    1.安装配置:https://www.cnblogs.com/ymwangel/p/5859453.html 2.使用 from pymongo import MongoClient #连接 conn ...

  7. 20、redis和memcached比较?

    1.Redis和Memcache都是将数据存放在内存中,都是内存数据库.不过memcache还可用于缓存其他东西,例如图片.视频等等: 2.Redis不仅仅支持简单的k/v类型的数据,同时还提供lis ...

  8. 转载:WebView

    前言 现在很多App里都内置了Web网页(Hyprid App),比如说很多电商平台,淘宝.京东.聚划算等等,如下图 那么这种该如何实现呢?其实这是Android里一个叫WebView的组件实现的.今 ...

  9. python中filter函数

    python中filter()函数   filter()函数是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断 ...

  10. O(1)时间复杂度实现入栈、出栈、获得栈中最小元素、获得栈中最大元素(转)

    题目要求:定义栈的数据结构,添加min().max()函数(动态获取当前状态栈中的最小元素.最大元素),要求push().pop().min().max()的时间复杂度都是O(1). 思路解析:根据栈 ...