DFS应用——遍历有向图+判断有向图是否有圈
【0】README
0.1) 本文总结于 数据结构与算法分析, 源代码均为原创, 旨在 理解 “DFS应用——遍历有向图+判断有向图是否有圈” 的idea 并用源代码加以实现 ;
0.2) 判断有向图是否有圈的rule—— 一个有向图是无圈图当且仅当它没有背向边,背向边定义,参见: http://blog.csdn.net/pacosonswjtu/article/details/49967255
0.3) ** 代码最后还添加了打印dfs遍历路径所产生的集合, 对的,dfs 就应该这么玩**,Bingo!
【1】有向图相关
1.1)对有向图进行DFS的idea:利用与无向图相同的思路, 也可以通过深度优先搜索以线性时间遍历有向图。如果图不是强连通的,那么从某个节点开始的DFS可能访问不了所有的节点。在这种情况下, 我们在某个未作标记的节点处开始,反复执行DFS, 直到所有节点都被访问到;
1.2)基于以上描述, 我们看个荔枝(这只是一种可能的case):
- step1)从顶点B 任意开始深度优先搜索, 访问顶点B, C, A, D, E;
- step2)从顶点 F 任意开始DFS, 访问顶点 F;
- step3)从顶点 H 任意开始DFS, 访问顶点 H, J, I;
- step4)从顶点 G 任意开始DFS, 访问顶点 G;
1.3)对于以上的DFS过程, 对应的搜索优先搜索树如下图所示:
对上图的分析(Analysis):
- A1)深度优先生成森林中虚线箭头是一些(v, w)边, 其中的w 在考察时已经做了标记;
- A2)我们看到,存在三种类型的边并不通向新顶点:
- A2.1)背向边:如(A,B) 和 (I,H);
- A2.2)前向边:如(C,D) 和 (C,E), 它们从树的一个节点通向一个后裔;
- A2.3)交叉边:如(F,C)和(G,F), 它们把不直接相关的两个树节点连接起来;
- A3)深度优先搜索森林一般通过吧一些子节点和一些新的树从左到右添加到森林中形成。 在以这种方式构成的有向图的深度优先搜索中,交叉边总是从右到左进行的;
1.4)深度优先搜索(DFS)的一个用途是: 检测一个有向图是否是无圈图;
- 4.1) 法则如下: 一个有向图是无圈图当且仅当它没有背向边;(上面的图有背向边, 因此它不是无圈图)
- 4.2)拓扑排序也可以用来确定一个图是否是无圈图。进行拓扑排序的另一种方法是通过深度优先生成森林的后序遍历给顶点指定拓扑编号N, N-1, ..., 1; 只要图是无圈的,这种排序就是一致的;
【2】source code + printing results(此处的dfs是对原始dfs修改而成的,与原始的dfs不同,但idea一样)
2.1)download source code: https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter9/p248_dfs_directed_graph
2.2)source code at a glance:(for complete code , please click the given link above)
void dfs(Vertex vertex, int depth)
{
int i;
int visitFlag;
AdjTable temp;
Vertex adjVertex;
//printf("\n\t visited[%c] = 1 ", flag[vertex]);
visited[vertex] = 1; // update visited status of vertex
vertexIndex[vertex] = counter++; // number the vertex with counter
temp = adj[vertex];
visitFlag = 0;
while(temp->next)
{
adjVertex = temp->next->vertex;
if(visited[adjVertex]) // judge whether the adjVertes was visited before
{
if(vertexIndex[vertex] > vertexIndex[adjVertex] && parent[vertex] != adjVertex)
{
parent[adjVertex] = vertex; // building back side, attention of condition of building back side above
// just for printing effect
for(i = 0; i < depth; i++)
printf(" ");
printf(" v[%c]->v[%c] (backside) \n", flag[vertex], flag[adjVertex]);
}
}
//if(!visited[adjVertex])
else
{
if(vertex == start)
visitFlag = 1;
parent[adjVertex] = vertex;
// just for printing effect
for(i = 0; i < depth; i++)
printf(" ");
printf(" v[%c]->v[%c] (building edge) \n", flag[vertex], flag[adjVertex]);
dfs(adjVertex, depth+1);
}
if(vertex == start && visitFlag) //conducingt dfs for only one adjoining vertex in the given graph
break;
temp = temp->next;
}
}
2.3)printing results(第二张图是对第一张图的补充,我最后添加了 dfsPathSet 方法打印出上述dfs遍历路径所产生的集合):
DFS应用——遍历有向图+判断有向图是否有圈的更多相关文章
- HDU3342:判断有向图中是否存在3元环-Tarjan或拓扑排序
题目大意: 给你一个关系图,判断是否合法.每个人都有师父和徒弟,可以有很多个: 若A是B的师父,B是C的师父,则A也算C的师父. 不合法: 1) . 互为师徒:(有回路) 2) .你的师父是你徒弟 ...
- hdu 1325 判断有向图是否为树
题意:判断有向图是否为树 链接:点我 这题用并查集判断连通,连通后有且仅有1个入度为0,其余入度为1,就是树了 #include<cstdio> #include<iostream& ...
- <数据结构>XDOJ323.判断有向图中是否有环
问题与解答 问题描述 判断有向图中是否有环. 输入格式 输入数据第一行是一个正整数,表示n个有向图,其余数据分成n组,每组第一个为一个整数,表示图中的顶点个数n,顶点数不超过100,之后为有向图的邻接 ...
- C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例
C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例 Unity中循环遍历每个数据,并做出判断 很多时候,游戏在玩家做出判断以后,游戏程序会遍历玩家身上大量的所需数据,然后做出判断,即首先判 ...
- (原创)不过如此的 DFS 深度优先遍历
DFS 深度优先遍历 DFS算法用于遍历图结构,旨在遍历每一个结点,顾名思义,这种方法把遍历的重点放在深度上,什么意思呢?就是在访问过的结点做标记的前提下,一条路走到天黑,我们都知道当每一个结点都有很 ...
- 采用邻接矩阵表示图的深度优先搜索遍历(与深度优先搜索遍历连通图的递归算法仅仅是DFS的遍历方式变了)
//采用邻接矩阵表示图的深度优先搜索遍历(与深度优先搜索遍历连通图的递归算法仅仅是DFS的遍历方式变了) #include <iostream> using namespace std; ...
- ZOJ 2475 Benny's Compiler(dfs判断有向图给定点有没有参与构成环)
B - Benny's Compiler Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu ...
- K - Strange Country II 暴力dfs判断有向图是否连通//lxm
You want to visit a strange country. There are n cities in the country. Cities are numbered from 1 t ...
- hdu1269迷宫城堡(判断有向图是否是一个强连通图)
1 /* 题意: 给你一个图,求这个有向图示否是一个强连通图(每两个节点都是可以相互到达的)! 思路1:按正向边dfs一遍,将经过的节点计数,如果记录的节点的个数小于n,那么就说明图按照正向边就不是连 ...
随机推荐
- ScriptableObject 对象化的运用
http://www.cnblogs.com/oldman/articles/2409554.html using UnityEngine; using UnityEditor; using Syst ...
- Jquery重新学习之二[属性attr(),removeAttr(),prop(),removeProp()]
1:属性.attr(name|pro|key,val|key,fn)与removeAttr(name) 1.1 .attr(name) 参数name为属性名称 <a id="my_hr ...
- jsp基本语法总结
一,用jsp脚本元素调用java代码 1,jsp表达式的应用 jsp表达式将值直接插入到输出中: <%= Java Expression %> 代表一个值 隐式对象,在使用jsp表达式的 ...
- LINUX下动态链接库的使用-dlopen dlsym dlclose dlerror
本定义 功能:打开一个动态链接库 包含头文件: #include <dlfcn.h> 函数定义: void * dlopen( const char * pathname, int mod ...
- perl: warning: Setting locale failed.
本篇文章由:http://xinpure.com/perl-warning-setting-locale-failed/ 将 mac 系统切换成英文后,使用 git 命令出现如下错误: perl: w ...
- MySQL查看和修改wait_timeout
1.全局查看wait_timeout值 mysql> show global variables like 'wait_timeout'; 2.修改全局wait_timeout值 set glo ...
- C# BeginInvoke和EndInvoke方法
转载自:BeginInvoke和EndInvoke方法 IDE:Visual Studio 2008 本系列教程主要包括如下内容:1. BeginInvoke和EndInvoke方法 2. Threa ...
- 转 springboot 教程
转 Spring Boot 揭秘与实战 系列 拓展阅读: https://zhuanlan.zhihu.com/dreawer?topic=Java 发表于 2016-12-21 | Spring框架 ...
- WiX and System Folders 系统目录 installshield 如何将文件安装到C盘根目录
Property name Brief description of property AdminToolsFolder Full path to the directory containing a ...
- id ,NSObject, id<NSObject>区别
转自:http://blog.csdn.net/happytengfei/article/details/11473931 我们经常会混淆以下三种申明(我是没有留意过): 1. id foo1; ...