图论算法——有向图的可达性与寻路
引言
本篇博文探讨了有向图的可达性(即给定起点与某个点是否连通)以及寻路问题。
有关图的概念可参考博文数据结构之图的概述
示例图如下:
有向图的可达性
利用了有向图的深度优先算法,它解决了单点连通性的问题,可以判定其他顶点和给定的起点是否连通。
package com.algorithms.graph;/*** @author yjw* @date 2019/5/20/020*/
public class DirectedDFS {private boolean[] marked;public DirectedDFS(DiGraph g, int s) {marked = new boolean[g.vertexNum()];dfs(g, s);}/*** 在有向图中找到从sources中的所有顶点可达的所有顶点** @param g* @param sources*/public DirectedDFS(DiGraph g, Iterable<Integer> sources) {marked = new boolean[g.vertexNum()];for (int s : sources) {if (!marked[s]) {dfs(g, s);}}}private void dfs(DiGraph g, int v) {marked[v] = true;for (int w : g.adj(v)) {if (!marked[w]) {dfs(g,w);}}}/*** 返回顶点v是从已知顶点(s或sources)中可达的吗* @param v* @return*/public boolean marked(int v) {return marked[v];}public static void main(String[] args) {DiGraph dg = new DiGraph(6);dg.addEdge(0,2,2,0,2,1,2,3,3,2,3,4,3,5);DirectedDFS dfs = new DirectedDFS(dg,3);for (int v = 0; v < dg.vertexNum(); v++) {if (dfs.marked[v]) {System.out.print(v + " ");}}System.out.println();}
}
我们验证了示例有向图,从3出发到所有顶点都是可达的。
有向图的寻路
package com.algorithms.graph;import com.algorithms.stack.Stack;/*** @author yjw* @date 2019/5/20/020*/
public class DepthFirstDirectedPaths {private boolean[] marked; private int[] edgeTo; private final int s; public DepthFirstDirectedPaths(DiGraph g, int s) {marked = new boolean[g.vertexNum()];edgeTo = new int[g.vertexNum()];this.s = s;dfs(g, s);}private void dfs(DiGraph g, int v) {marked[v] = true;for (int w : g.adj(v)) {if (!marked[w]) {edgeTo[w] = v;dfs(g, w);}}}public boolean hasPathTo(int v) {return marked[v];}public Iterable<Integer> pathTo(int v) {if (!hasPathTo(v)) return null;Stack<Integer> path = new Stack<>();for (int x = v; x != s; x = edgeTo[x]) {path.push(x);}path.push(s);return path;}public static void main(String[] args) {DiGraph g = new DiGraph(6);g.addEdge(0,2,2,0,2,1,2,3,3,2,3,4,3,5);int s = 3;DepthFirstDirectedPaths dfs = new DepthFirstDirectedPaths(g, s);for (int v = 0; v < g.vertexNum(); v++) {if (dfs.hasPathTo(v)) {System.out.printf("%d to %d: ", s, v);for (int x : dfs.pathTo(v)) {if (x == s) {System.out.print(x);} else {System.out.print("->" + x);}}System.out.println();}else {System.out.printf("%d to %d: not connected\n", s, v);}}}}
可以利用深度优先搜索回答有向图中给定起点到某个顶点是否有路径的问题(可达性)。
上面构造了我们示例中的有向图,输出如下:
3 to 0: 3->2->0
3 to 1: 3->2->1
3 to 2: 3->2
3 to 3: 3
3 to 4: 3->4
3 to 5: 3->5
类似的,还可以得出有向图的最短路径。
package com.algorithms.graph;import com.algorithms.queue.Queue;
import com.algorithms.stack.Stack;/*** @author yjw* @date 2019/5/20/020*/
public class BreadthFirstDirectedPaths {private boolean[] marked;/*** 到达当前顶点的最近顶点*/private int[] edgeTo;private final int s;public BreadthFirstDirectedPaths(DiGraph g, int s) {marked = new boolean[g.vertexNum()];edgeTo = new int[g.vertexNum()];this.s = s;bfs(g, s);}private void bfs(DiGraph g, int s) {Queue<Integer> queue = new Queue<>();marked[s] = true;queue.enqueue(s);while (!queue.isEmpty()) {int v = queue.dequeue();/*** 将与v相邻的所有未被标记的顶点加入队列*/for (int e: g.adj(v)) {if (!marked[e]) {marked[e] = true;edgeTo[e] = v;queue.enqueue(e);}}}}public boolean hasPathTo(int v) {return marked[v];}public Iterable<Integer> pathTo(int v) {if (!hasPathTo(v)) {return null;}Stack<Integer> path = new Stack<>();/*** 从路径终点一步步寻找前一个顶点*/for (int x = v; x != s ; x = edgeTo[x]) {path.push(x);}/*** 利用栈后进先出刚好可以顺序打印路径上所有顶点*/path.push(s);return path;}public static void main(String[] args) {DiGraph g = new DiGraph(6);g.addEdge(0,2,2,0,2,1,2,3,3,2,3,4,3,5);int s = 0;BreadthFirstDirectedPaths bfs = new BreadthFirstDirectedPaths(g, s);for (int v = 0; v < g.vertexNum(); v++) {if (bfs.hasPathTo(v)) {System.out.printf("%d to %d: ", s, v);for (int x : bfs.pathTo(v)) {if (x == s) {System.out.print(x);} else {System.out.print("->" + x);}}System.out.println();}else {System.out.printf("%d to %d (-): not connected\n", s, v);}}}
}
图论算法——有向图的可达性与寻路相关推荐
- Algorithm:C++语言实现之图论算法相关(图搜索广度优先BFS、深度优先DFS,最短路径SPF、带负权的最短路径Bellman-ford、拓扑排序)
Algorithm:C++语言实现之图论算法相关(图搜索广度优先BFS.深度优先DFS,最短路径SPF.带负权的最短路径Bellman-ford.拓扑排序) 目录 一.图的搜索 1.BFS (Brea ...
- warshall算法求传递闭包c++_【建模小课堂】图论算法
图论算法 图论算法在计算机科学中扮演着很重要的角色,它提供了对很多问题都有效的一种简单而系统的建模方式.很多问题都可以转化为图论问题,然后用图论的基本算法加以解决.这类问题算法主要包括Dijkstra ...
- 数学建模图论算法学习总结
数学建模图论算法学习总结 图论基本知识 B站视频: https://www.bilibili.com/video/av18374161/?p=35 https://www.bilibili.com/v ...
- 补学图论算法:算法竞赛入门经典(第二版)第十一章:
补学图论算法:算法竞赛入门经典(第二版)第十一章: 倒排索引还没有实现! 下面是左神的图论算法,并查集笔记.和一个美团题目. ''' https://www.nowcoder.com/live/11? ...
- 图论算法之最短路径(Dijkstra、Floyd、Bellman-ford和SPFA)
图论算法之最短路径(Dijkstra.Floyd.Bellman-ford和SPFA) 1.图论最短路径概述 图论算法为了求解一个顶点到另一个顶点的最短路径,即如果从图中某一顶点(称为源点)到达另一顶 ...
- 图论算法(5):图的广度优先遍历 BFS
本章节内容使用 java 实现,Github 代码仓:https://github.com/ZhekaiLi/Code/tree/main/Graph/src 查看文章内的图片可能需要科学上网! 因为 ...
- 图论算法:图论基础介绍
图论相关定义 一个图(graph) G = (V, E) 由顶点(vertex)的集合 V 和 边(edge)的集合E组成,有时也把边称作弧(arc).如果图中的边是带方向的,那么图就是有向图(dir ...
- NOIp 图论算法专题总结 (1):最短路、最小生成树、最近公共祖先
系列索引: NOIp 图论算法专题总结 (1) NOIp 图论算法专题总结 (2) NOIp 图论算法专题总结 (3) 最短路 Floyd 基本思路:枚举所有点与点的中点,如果从中点走最短,更新两点间 ...
- c语言a 寻路算法,JS/HTML5游戏常用算法之路径搜索算法 A*寻路算法完整实例
本文实例讲述了JS/HTML5游戏常用算法之路径搜索算法 A*寻路算法.分享给大家供大家参考,具体如下: 完整实例代码如下: A*寻路算法 #stage { border: 1px solid lig ...
- 图论算法(二)-最短路径的Dijkstra [ 单源 ] 和Floyd[ 多源 ] 解法(JAVA )
一.Dijkstra算法 问题描述:求一个点到任意个点的距离 思路:单源最短路径问题,使用Dijkstra算法 Input: 6 9 1 2 1 1 3 12 2 3 9 2 4 3 3 5 5 4 ...
最新文章
- 大数据时代的数据管理
- Python基础之:函数
- PL/SQL块中不能直接执行DDL语句(错误)
- android h5 有广告,那些H5在Android上显示的丧心病狂的坑
- linux查看svn信息,SVN 查看历史信息
- 游戏计算机软著登记证书,“VR沙盘游戏心理疗法软件”取得计算机软件著作权登记证书...
- 机器学习算法之GMM模型
- 第二人生的源码分析(九十七)LLSlider实现音量滑动条
- 怎样推导圆面积计算公式?
- 安装个https证书要多少钱
- 谷歌Chrome浏览器主页被毒霸篡改
- Map map=new HashMap(); 为什么是这样
- JAVASE阶段测试试卷
- java 日期处理_java日期处理总结
- Markdown 语法学习
- 洛谷P1426 小鱼会有危险吗
- 广西田园及20家子公司引入契约锁电子签章,提升经销商服务效率
- 保研面试 算法题_计算机考研/保研复试重点整理-数据结构篇
- OpenFOAM不可压求解器pimpleFoam研究(一)粘度实现
- U盘重装 Windows 系统笔记