Bellman_Ford算法和Dijkstra算法都可以用来求解有向图的单源最短路径问题,但是,相比于Dijkstra算法, Bellman_Ford算法允许边的权重为负值。

算法的详细讨论见算法导论或者下面这个博客http://blog.csdn.net/niushuai666/article/details/6791765

代码如下:

#include<iostream>using namespace std;#define Inf 65535
#define NotAVerter -1/邻接链表的相关定义//
typedef struct EdgeNode *position;
typedef struct Led_table* Table;struct EdgeNode     //边表结点
{int adjvex;    // 邻接点域,存储该顶点对应的下标int weight;     // 对应边的权值int dis;     //此数据记录从源点到该节点的最短距离int precursor;  //此数据记录该节点在广度优先树种的前驱节点position next; // 链域,指向下一个邻接点
};struct Led_table       // 邻接表结构
{int data;                //邻接表的大小position *firstedge;       //边表头指针,可以理解为数组
};//邻接链表相关函数定义///
Table Creat_Lable(int MaxElements)    //MaxElements参数为希望创建的节点数
{Table table1 = static_cast<Table> (malloc(sizeof(struct Led_table)));table1->data = MaxElements;if (table1 == NULL){cout << "out of space!!!";}table1->firstedge = static_cast<position*>(malloc(sizeof(position)*(table1->data)));if (table1->firstedge == NULL){cout << "out of space!!!";}//给每个表头赋值,从0开始for (int i = 0; i <= table1->data - 1; ++i){table1->firstedge[i] = static_cast<position>(malloc(sizeof(EdgeNode)));   //申请一个节点if (table1->firstedge[i] == NULL){cout << "out of space!!!";}table1->firstedge[i]->adjvex = 0;   //表头这个参数没有意义table1->firstedge[i]->weight = 0;   //表头这个参数没有意义table1->firstedge[i]->dis = Inf;table1->firstedge[i]->precursor = NotAVerter;table1->firstedge[i]->next = NULL;}return table1;}void Insert(Table table1, int v, int w, int weig)   //表示存在一条边为<v,w>
{position p = static_cast<position>(malloc(sizeof(EdgeNode)));   //申请一个节点if (p == NULL){cout << "out of space!!!";}p->adjvex = w;p->weight = weig;    //对于无权图来说,该域可以设置为1p->dis = Inf;    //对于普通节点来说无意义p->precursor = NotAVerter;  //对于普通节点来说无意义p->next = table1->firstedge[v]->next;table1->firstedge[v]->next = p;}void init_yuandian(Table table1, int s)  //把s设置为图的源点
{table1->firstedge[s]->adjvex = 0;table1->firstedge[s]->weight = 0;table1->firstedge[s]->dis = 0;    //源点的这个值设置为0table1->firstedge[s]->precursor = NotAVerter;
}bool Bellman_Ford(Table table1, int s)
{for (int i = 1; i <= table1->data - 1; ++i)   //每条边进行N-1次松弛操作{for (int j = 0; j <= table1->data - 1; ++j)  //对每条边{position p = table1->firstedge[j]->next;while (p != NULL){if (table1->firstedge[p->adjvex]->dis > table1->firstedge[j]->dis + p->weight)   //松弛操作{table1->firstedge[p->adjvex]->dis = table1->firstedge[j]->dis + p->weight;table1->firstedge[p->adjvex]->precursor = j;}p = p->next;}}}bool flag = true;for (int j = 0; j <= table1->data - 1; ++j)  //对每条边{position p = table1->firstedge[j]->next;while (p != NULL){if (table1->firstedge[p->adjvex]->dis > table1->firstedge[j]->dis + p->weight){flag = false;break;}p = p->next;}}return flag;
}void print_path(Table table1, int v)
{if (table1->firstedge[v]->precursor != NotAVerter)print_path(table1, table1->firstedge[v]->precursor);cout << "v" << v << endl;
}int main()
{Table table_1 = Creat_Lable(5);    //创建一个大小为5的邻接表Insert(table_1, 0, 1, 6); Insert(table_1, 0, 3, 7);Insert(table_1, 1, 2, 5); Insert(table_1, 1, 3, 8); Insert(table_1, 1, 4, -4);Insert(table_1, 2, 1, -2);Insert(table_1, 3, 2, -3); Insert(table_1, 3, 4, 9);Insert(table_1, 4, 0, 2); Insert(table_1, 4, 2, 7); init_yuandian(table_1, 0);  //把0设置为图的源点cout << Bellman_Ford(table_1, 0) << endl;cout << table_1->firstedge[4]->dis << endl;print_path(table_1, 4);return 0;
}

  夜深了,夜更深了

转载于:https://www.cnblogs.com/1242118789lr/p/7648011.html

Bellman_Ford算法相关推荐

  1. 含有负边的图的最短路径(Bellman_ford算法)

    更新所有的边,每条边更新V-1次,时间复杂度为O(V*E). 有些更新操作是重复了的,这里可以考虑检查多余的重复操作作,如果没有更新发生,则立即终止算法. #include<iostream&g ...

  2. usaco Sweet Butter(迪杰斯特拉(优先队列优化),bellman_ford算法模板)

    这题开始用没有优化的迪杰斯特拉喜闻乐见的超时了,然后我用bellmanford算法按理说时间复杂度更大但是书上说往往只要很短的时间就可以求出最短路. 所以我用了这个算法但是我对这个算法还是不熟套了模板 ...

  3. poj3259(Bellman_ford算法)

    Bellman - ford算法:是求含负权图的单源最短路径的一种算法,效率较低,代码难度较小.其原理为连续进行松弛,在每次松弛时把每条边都更新一下,若在n-1次松弛后还能更新,则说明图中有负环,因此 ...

  4. *【POJ - 1860】Currency Exchange (单源最长路---Bellman_Ford算法判正环)

    题干: Description Several currency exchange points are working in our city. Let us suppose that each p ...

  5. 853. 有边数限制的最短路(bellman_ford算法)

    给定一个 nn 个点 mm 条边的有向图,图中可能存在重边和自环, 边权可能为负数. 请你求出从 11 号点到 nn 号点的最多经过 kk 条边的最短距离,如果无法从 11 号点走到 nn 号点,输出 ...

  6. Bellman_Ford算法(求一个点到任意一点的最短距离)

    单源最短路问题是固定一个起点,求它到任意一点最短路的问题. 记从起点出发到顶点 i 的最短距离为d[i],则有以下等式成立 d[i]=min{d[j]+(从j到 i 的边的权值) 看代码 #inclu ...

  7. bellman_ford算法 由边数限制的最短路

    首先认真读题:(acwing853) 给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环, 边权可能为负数. 请你求出从 1 号点到 n号点的最多经过 k 条边的最短距离,如果无法从 1 号 ...

  8. poj 3259 时光穿梭问题 bellman_ford算法

    题意:有n个空地,有m条双向大路,w条时光隧道单向路.问能否回到过去? 思路:判断是否有负环存在,如果有负环存在那么就可以一直小就可以回到过去了 创建源顶点 V到其他顶点的距离d 初始为INF d[1 ...

  9. 【POJ - 3259 】Wormholes(Bellman_Ford或spfa算法,判断有向图中是否存在负环)

    题干: 农夫约翰在探索他的许多农场,发现了一些惊人的虫洞.虫洞是很奇特的,因为它是一个单向通道,可让你进入虫洞的前达到目的地!他的N(1≤N≤500)个农场被编号为1..N,之间有M(1≤M≤2500 ...

最新文章

  1. Science Robotics近日刊登CMU重大突破,无需手术,普通人就能用意念操控机械臂!...
  2. ssl2339 分糖果 spfa
  3. Java使用PDFBox开发包实现对PDF文档内容编辑与保存
  4. Java Applet读写client串口——终极篇
  5. 十一、“由专入分易,由分入专难。”(2020.12.18)
  6. 半正定矩阵的判定方法_线性代数30——正定矩阵和最小值
  7. Linux重启提示A stop job is running for ...
  8. Linux内核学习编译流程
  9. 计算机组成原理试卷分析,《计算机组成原理与汇编语言》试卷分析报告.doc.docx...
  10. Android获取所在城市坐标及城市信息(逆地理位置编码)
  11. 一封没有读出来的感谢信,勾勒出蔡文胜30年创业史!
  12. 2020-1024=996(程序员节)
  13. GMQ钱包积极打造并维护区块链健康生态的发展
  14. 阿里云网站备案时变更备案的问题解决总结 满满干货
  15. 实用计算机理论基础知识试题及答案,计算机基础知识试题库及答案(5)
  16. 263企业邮箱imap服务器,263企业邮箱实现IMAP邮箱搬家功能
  17. 【Word文档修改过程中空格下划线打印不出来问题解决】
  18. 告诉你怎么编写一个最简单的单片机程序
  19. angular打包文件目录及访问地址
  20. Java面向对象的编程⑤面向对象

热门文章

  1. mybatis 批量增加 Parameter '__frch_item_0' not found. Available parameters are [list]
  2. 破解微软xp黑屏方法
  3. 使用charles对vue项目进行map Local功能mock数据页面不正常显示
  4. 关于 equals 和 hashCode,看这一篇真的够了!
  5. 字节跳动面试题:“请你描述下 Spring Bean 的生命周期?”
  6. 我才是世界上最好的编程语言
  7. An error happened during template parsing (template: class path resource [templates/emp/list.html]
  8. java程序死了telnet还有用吗_java实现telnet连接操作 改进
  9. dma访问主存时_STM32F103单片机(五)——DMA
  10. es 插入数据_记录一次Java导入百万级数据到Elasticsearch经历