题目:

  最短路:给定两个顶点,在以这两个点为起点和终点的路径中,边的权值和最小的路径。考虑权值为点之间的距离。

  单源最短路问题,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算法的更多相关文章

  1. Bellman—Ford算法思想

    ---恢复内容开始--- Bellman—Ford算法能在更普遍的情况下(存在负权边)解决单源点最短路径问题.对于给定的带权(有向或无向)图G=(V,E),其源点为s,加权函数w是边集E的映射.对图G ...

  2. Bellman - Ford 算法解决最短路径问题

    Bellman - Ford 算法: 一:基本算法 对于单源最短路径问题,上一篇文章中介绍了 Dijkstra 算法,但是由于 Dijkstra 算法局限于解决非负权的最短路径问题,对于带负权的图就力 ...

  3. Dijkstra算法与Bellman - Ford算法示例(源自网上大牛的博客)【图论】

    题意:题目大意:有N个点,给出从a点到b点的距离,当然a和b是互相可以抵达的,问从1到n的最短距离 poj2387 Description Bessie is out in the field and ...

  4. poj1860 bellman—ford队列优化 Currency Exchange

    Currency Exchange Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 22123   Accepted: 799 ...

  5. uva 558 - Wormholes(Bellman Ford判断负环)

    题目链接:558 - Wormholes 题目大意:给出n和m,表示有n个点,然后给出m条边,然后判断给出的有向图中是否存在负环. 解题思路:利用Bellman Ford算法,若进行第n次松弛时,还能 ...

  6. ACM/ICPC 之 最短路径-Bellman Ford范例(POJ1556-POJ2240)

    两道Bellman Ford解最短路的范例,Bellman Ford只是一种最短路的方法,两道都可以用dijkstra, SPFA做. Bellman Ford解法是将每条边遍历一次,遍历一次所有边可 ...

  7. 图论算法——最短路径Dijkstra,Floyd,Bellman Ford

    算法名称 适用范围 算法过程 Dijkstra 无负权 从s开始,选择尚未完成的点中,distance最小的点,对其所有边进行松弛:直到所有结点都已完成 Bellman-Ford 可用有负权 依次对所 ...

  8. 最短路问题的三种算法&模板

    最短路算法&模板 最短路问题是图论的基础问题.本篇随笔就图论中最短路问题进行剖析,讲解常用的三种最短路算法:Floyd算法.Dijkstra算法及SPFA算法,并给出三种算法的模板.流畅阅读本 ...

  9. POJ 2240 Arbitrage (Bellman Ford判正环)

    Arbitrage Time Limit: 1000MS   Memory Limit: 65536K Total Submissions:27167   Accepted: 11440 Descri ...

  10. poj1860 兑换货币(bellman ford判断正环)

    传送门:点击打开链接 题目大意:一个城市有n种货币,m个货币交换点,你有v的钱,每个交换点只能交换两种货币,(A换B或者B换A),每一次交换都有独特的汇率和手续费,问你存不存在一种换法使原来的钱更多. ...

随机推荐

  1. swap分析及其使用

    什么是swap swap主要是在内存不够用的时候,将部分内存上的数据交换到swap空间上,以便让系统不会因为内存不够用而导致oom或者更致命的情况出现.当内存使用存在压力的时候,开始触发内存回收行为, ...

  2. Sublime Text 3安装SFTP插件

    前言: 最近在学习网页设计,陆续接触到了HTML.CSS和JavaScript,写的代码越来越多了,也越来越感觉到将代码上传到服务器上的流程太繁琐了.一开始我是用虚拟主机提供的控制面板下载上传网页代码 ...

  3. ubuntu16.04如何安装搜狗输入法

    1 . 首先我们需要先来下载支持linux版本的搜狗输入法安装包,这里我们先查看下自己的ubuntu系统是什么版本的,这里我们可以在右上角的那个齿轮图标点击查看"系统设置",在里面 ...

  4. freemarker导出word文档

    使用freemarker导出word文档的过程 **************************************************************************** ...

  5. Math.pow();Math.sqrt();

    //Math.pow(a,b)功能是a的b次方 (int)Math.sqrt(n):先对n开方,然后转成int类型//例如,(int)Math.sqrt(2)=(int)1.414=1 Math.ab ...

  6. 【dfs+连通分量】Bzoj1123 POI2008 BLO

    Description Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通. Input 输入n&l ...

  7. BZOJ_4530_[Bjoi2014]大融合_LCT

    BZOJ_4530_[Bjoi2014]大融合_LCT Description 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个 ...

  8. Linux下可以ping ip地址但无法ping域名解决方法

    分析:当前系统无法解决域名至ip地址故障. 步骤阅读 2 三:解决过程: 1.分析dns故障: 2.物理机可以ping 地址,但无法ping域名: 3.检查/etc/resolv.conf: 注: ( ...

  9. 显著性检测(saliency detection)评价指标之KL散度距离Matlab代码实现

    步骤1:先定义KLdiv函数: function score = KLdiv(saliencyMap, fixationMap) % saliencyMap is the saliency map % ...

  10. Python并发编程之深入理解yield from语法(八)

    大家好,并发编程 进入第八篇. 直到上一篇,我们终于迎来了Python并发编程中,最高级.最重要.当然也是最难的知识点--协程. 当你看到这一篇的时候,请确保你对生成器的知识,有一定的了解.当然不了解 ...