最短路问题之Bellman-ford算法
题目:
最短路:给定两个顶点,在以这两个点为起点和终点的路径中,边的权值和最小的路径。考虑权值为点之间的距离。
单源最短路问题,Bellman-ford算法
思路:每次循环检查所有边,可优化。
应用于旅游等路径最小问题。
代码:
import java.util.Arrays;
public class 图的最短路问题_单源 {
public static void main(String[] args) {
int[] shortestPath = shortestPath(0);
System.out.println(Arrays.toString(shortestPath));
// 输出[0, 2, 5, 7, 11, 8, 16]
}
/**
* 求起点到各顶点的最短距离
*
* @param s 起点
* @return
*/
private static int[] shortestPath(int s) {
int n = graph.length;
// 记录s到各顶点的最短距离
int[] d = new int[n];
for (int i = 0; i < n; i++) {
d[i] = Integer.MAX_VALUE;
}
d[s] = 0;// 到自己的距离为0
while (true) {
boolean update = false;
// 扫描所有的边
for (int i = 0; i < n; i++) {
// 起点到i的最短距离还没算出来
if (d[i] == Integer.MAX_VALUE)
continue;
for (int j = 0; j < n; j++) {
int cost = graph[i][j]; // i,j之间的距离
if (cost > 0) { // i,j 两点之间有边,起点是i
if (d[j] > d[i] + cost) { // 起点先到i,i->j
// 两端距离加起来比起点直接到j的距离短,则更新
update = true;
d[j] = d[i] + cost;
}
}
}
}
// 无需任何更新,退出外循环
if (!update)
break;
}
return d;
}
static int[][] graph = {
{ 0, 2, 5, 0, 0, 0, 0 },
{ 2, 0, 4, 6, 10, 0, 0 },
{ 5, 4, 0, 2, 0, 0, 0 },
{ 0, 6, 2, 0, 0, 1, 0 },
{ 0, 10, 0, 0, 0, 3, 5 },
{ 0, 0, 0, 1, 3, 0, 9 },
{ 0, 0, 0, 0, 5, 9, 0 }
};
}
对于上一个代码。可以先把边集提取出来,这样不用每次扫描二维数组。
Edge类:
/**
* 边 的封装
* 边集可以用来表示图
*/
public class Edge<T> implements Comparable<Edge> {
private T start;
private T end;
private int distance; public Edge(T start, T end, int distance) {
this.start = start;
this.end = end;
this.distance = distance;
} public T getStart() {
return start;
} public void setStart(T start) {
this.start = start;
} public T getEnd() {
return end;
} public void setEnd(T end) {
this.end = end;
} public int getDistance() {
return distance;
} public void setDistance(int distance) {
this.distance = distance;
} @Override
public String toString() {
return start + "->" + end + ":" + distance;
} @Override
public int compareTo(Edge obj) {
int targetDis = obj.getDistance();
return distance > targetDis ? 1 : (distance == targetDis ? 0 : -1);
}
}
优化过后的代码:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; public class 图的最短路问题_优化_边集 {
public static void main(String[] args) {
edges = buildEdges(graph);
int[] shortestPath = shortestPath(0);
System.out.println(Arrays.toString(shortestPath));
// 输出[0, 2, 5, 7, 11, 8, 16]
} /**
* 求起点到各顶点的最短距离
*
* @param s
* 起点
* @return
*/
private static int[] shortestPath(int s) {
int n = graph.length;
// 记录s到各顶点的最短距离
int[] d = new int[n];
for (int i = 0; i < n; i++) {
d[i] = Integer.MAX_VALUE;
}
d[s] = 0;// 到自己的距离为0
while (true) {
boolean update = false; for (Edge<Integer> e : edges) {
if (d[e.getStart()] != Integer.MAX_VALUE && d[e.getEnd()] > d[e.getStart()] + e.getDistance()) {
update = true;
d[e.getEnd()] = d[e.getStart()] + e.getDistance();
}
} if (!update)
break;
}
return d;
} static List<Edge<Integer>> edges; static List<Edge<Integer>> buildEdges(int[][] graph) {
int n = graph.length;
List<Edge<Integer>> edges = new ArrayList<>();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int cost = graph[i][j]; // i,j之间的距离
if (cost > 0) { // i,j 两点之间有边,起点是i
edges.add(new Edge<>(i, j, cost));
}
}
}
return edges;
} static int[][] graph = {
{ 0, 2, 5, 0, 0, 0, 0 },
{ 2, 0, 4, 6, 10, 0, 0 },
{ 5, 4, 0, 2, 0, 0, 0 },
{ 0, 6, 2, 0, 0, 1, 0 },
{ 0, 10, 0, 0, 0, 3, 5 },
{ 0, 0, 0, 1, 3, 0, 9 },
{ 0, 0, 0, 0, 5, 9, 0 }
};
}
最短路问题之Bellman-ford算法的更多相关文章
- Bellman—Ford算法思想
---恢复内容开始--- Bellman—Ford算法能在更普遍的情况下(存在负权边)解决单源点最短路径问题.对于给定的带权(有向或无向)图G=(V,E),其源点为s,加权函数w是边集E的映射.对图G ...
- Bellman - Ford 算法解决最短路径问题
Bellman - Ford 算法: 一:基本算法 对于单源最短路径问题,上一篇文章中介绍了 Dijkstra 算法,但是由于 Dijkstra 算法局限于解决非负权的最短路径问题,对于带负权的图就力 ...
- Dijkstra算法与Bellman - Ford算法示例(源自网上大牛的博客)【图论】
题意:题目大意:有N个点,给出从a点到b点的距离,当然a和b是互相可以抵达的,问从1到n的最短距离 poj2387 Description Bessie is out in the field and ...
- poj1860 bellman—ford队列优化 Currency Exchange
Currency Exchange Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 22123 Accepted: 799 ...
- uva 558 - Wormholes(Bellman Ford判断负环)
题目链接:558 - Wormholes 题目大意:给出n和m,表示有n个点,然后给出m条边,然后判断给出的有向图中是否存在负环. 解题思路:利用Bellman Ford算法,若进行第n次松弛时,还能 ...
- ACM/ICPC 之 最短路径-Bellman Ford范例(POJ1556-POJ2240)
两道Bellman Ford解最短路的范例,Bellman Ford只是一种最短路的方法,两道都可以用dijkstra, SPFA做. Bellman Ford解法是将每条边遍历一次,遍历一次所有边可 ...
- 图论算法——最短路径Dijkstra,Floyd,Bellman Ford
算法名称 适用范围 算法过程 Dijkstra 无负权 从s开始,选择尚未完成的点中,distance最小的点,对其所有边进行松弛:直到所有结点都已完成 Bellman-Ford 可用有负权 依次对所 ...
- 最短路问题的三种算法&模板
最短路算法&模板 最短路问题是图论的基础问题.本篇随笔就图论中最短路问题进行剖析,讲解常用的三种最短路算法:Floyd算法.Dijkstra算法及SPFA算法,并给出三种算法的模板.流畅阅读本 ...
- POJ 2240 Arbitrage (Bellman Ford判正环)
Arbitrage Time Limit: 1000MS Memory Limit: 65536K Total Submissions:27167 Accepted: 11440 Descri ...
- poj1860 兑换货币(bellman ford判断正环)
传送门:点击打开链接 题目大意:一个城市有n种货币,m个货币交换点,你有v的钱,每个交换点只能交换两种货币,(A换B或者B换A),每一次交换都有独特的汇率和手续费,问你存不存在一种换法使原来的钱更多. ...
随机推荐
- KVM内核文档阅读笔记
KVM在内核中有丰富的文档,位置在Documentation/virtual/kvm/. 00-INDEX:整个目录的索引及介绍文档. api.txt:KVM用户空间API,所谓的API主要是通过io ...
- c#Socket客户端和服务端的信息发送
这是我制作的界面信息,c# Socket通信的简单使用,刚开始学习,不对的地方请大家指教,目前是可以运行的,之后自己在慢慢添加新的东西.同时了解Tcp协议的三次握手.希望对跟我一样的初学者有所帮助. ...
- 第三期分享:一款很好用的api文档生成器
主要用途:生成API的文档 源码链接:https://github.com/tmcw/docbox 最近刚好在看:Trending in open source,在JS语言中,slate一直在周排行上 ...
- 1. 开篇-springboot环境搭建
最初学习strurs2时,虽然觉得也挺好用的,但也有一些不便的地方:1. 模型绑定必须要在Action中声明对应模型的成员变量:2. Action中对外提供调用的接口必须明确注明:3. 要声明一大堆的 ...
- switch case 支持的 6 种数据类型!
有粉丝建议可以偶尔推送一些 Java 方面的基础知识,一方面可以帮助一初学者,也可以兼顾中高级的开发者. 那么今天就讲一下 Java 中的 switch case 语句吧,有忘记的同学正好可以温习一下 ...
- I/O-----二进制文件的读写
好吧 已经被I/O刷屏了 这是复制文件 DataInputStream dis =new DataInputStream(new FileInputStream("src/pcl.jpg ...
- JUnit 异常处理
java.lang.Exception: No tests found matching [{ExactMatcher:fDisplayName=testfindAll], {ExactMatcher ...
- Linux 下配置Nginx,MySql,php-fpm开机启动
一. Nginx 开机启动 1.在/etc/init.d/目录下创建脚本 vim /etc/init.d/nginx 2.编写脚本内容 (将以下复制进去相应改动安装路径) #!/bin/bash # ...
- react VS vue 我们究竟该如何选择(从项目的角度帮你分析)
一.序言 现在web开发最火的两个框架,react和vue.听起来就感觉很牛逼的样子.确实,不得不服,创造出这2种框架的人真的是牛逼.不过更牛逼的是为这2中框架不断完善的人.一个优秀的idea,会在很 ...
- python里面的xlrd模块详解(一)
那我就一下面积个问题对xlrd模块进行学习一下: 1.什么是xlrd模块? 2.为什么使用xlrd模块? 3.怎样使用xlrd模块? 1.什么是xlrd模块? python操作excel主要用到xlr ...