【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应用——遍历有向图+判断有向图是否有圈的更多相关文章

  1. HDU3342:判断有向图中是否存在3元环-Tarjan或拓扑排序

    题目大意: 给你一个关系图,判断是否合法.每个人都有师父和徒弟,可以有很多个: 若A是B的师父,B是C的师父,则A也算C的师父. 不合法:  1) . 互为师徒:(有回路)  2) .你的师父是你徒弟 ...

  2. hdu 1325 判断有向图是否为树

    题意:判断有向图是否为树 链接:点我 这题用并查集判断连通,连通后有且仅有1个入度为0,其余入度为1,就是树了 #include<cstdio> #include<iostream& ...

  3. <数据结构>XDOJ323.判断有向图中是否有环

    问题与解答 问题描述 判断有向图中是否有环. 输入格式 输入数据第一行是一个正整数,表示n个有向图,其余数据分成n组,每组第一个为一个整数,表示图中的顶点个数n,顶点数不超过100,之后为有向图的邻接 ...

  4. C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例

    C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例 Unity中循环遍历每个数据,并做出判断 很多时候,游戏在玩家做出判断以后,游戏程序会遍历玩家身上大量的所需数据,然后做出判断,即首先判 ...

  5. (原创)不过如此的 DFS 深度优先遍历

    DFS 深度优先遍历 DFS算法用于遍历图结构,旨在遍历每一个结点,顾名思义,这种方法把遍历的重点放在深度上,什么意思呢?就是在访问过的结点做标记的前提下,一条路走到天黑,我们都知道当每一个结点都有很 ...

  6. 采用邻接矩阵表示图的深度优先搜索遍历(与深度优先搜索遍历连通图的递归算法仅仅是DFS的遍历方式变了)

    //采用邻接矩阵表示图的深度优先搜索遍历(与深度优先搜索遍历连通图的递归算法仅仅是DFS的遍历方式变了) #include <iostream> using namespace std; ...

  7. ZOJ 2475 Benny's Compiler(dfs判断有向图给定点有没有参与构成环)

    B - Benny's Compiler Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu ...

  8. 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 ...

  9. hdu1269迷宫城堡(判断有向图是否是一个强连通图)

    1 /* 题意: 给你一个图,求这个有向图示否是一个强连通图(每两个节点都是可以相互到达的)! 思路1:按正向边dfs一遍,将经过的节点计数,如果记录的节点的个数小于n,那么就说明图按照正向边就不是连 ...

随机推荐

  1. 〖Android〗(CM10.2)Android4.2/4.3中的boot.img打包方法(合适三星exynos4 CPU)

    #!/bin/bash - #=============================================================================== # # F ...

  2. 调试Felix Framework

    这里是指用Eclipse调试Felix Framework自身. 1. 首先安装Eclipse Java EE,然后再安装Java Source Attacher,这样才会在Jar文件的右键菜单“属性 ...

  3. MySQL-锁研究

    隔离级别研究: http://www.cnblogs.com/JohnABC/p/3521061.html 表级:引擎 MyISAM, 理解为锁住整个表, 锁定期间, 其它进程无法对该表进行写操作, ...

  4. 发布WebService 1.1

    webservice1.1是基于jdk发布的 package cn.itcast.service01; import javax.jws.WebService; import javax.xml.ws ...

  5. Ubuntu 分区方案参考

    2011-10-25 10:09   对于初次接触的一般用户(包括双系统用户): /             5-10G(玩玩的话5G就够,长期使用的话推荐10G) /usr         5-10 ...

  6. mysql数据结构优化,范式和反范式

    1.范式,正常的建表,反范式,为了提高效率,适当的已空间换时间 2.垂直拆分,就是把经常用的.或者text大存储的字段单独拉出来存表 3.水平拆分,解决数据量大的问题,进行取莫的方式将数据放到相同的n ...

  7. STS(Spring Tool Suite)创建maven项目

    右键菜单选择新建->maven项目 自己创建存放配置文件需要使用的maven文件夹

  8. 给Editplus去掉.bak文件

    Tools-->Configure User Tools-->Files-->去掉create bacup file when saving前复选框的对号.

  9. mysql 用户自定义变量

    SQL中可以用变量来操作值.那么问题就来了.mysql中怎么定义一个变量呢? 一.定义变量 1.定义变量的语法: set @var_name=expr [,@var_name=expr] ... 2. ...

  10. SQL Server 2008、SQL Server 2008R2 自动备份数据库

    让SQL Server 2008自动备份数据库,需要建立一个SQL Server作业,并启动SQL Server代理,使该作业定期运行. 具体来说,可以按以下步骤进行: 一.打开SQL Server ...