【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. UNIX网络编程读书笔记:poll函数

    poll函数提供的功能与select类似,不过在处理流设备时,它能够提供额外的信息. poll函数原型 #include <poll.h> int poll(struct pollfd * ...

  2. QQ互联简单例子,七彩花都提供

    QQ互联简单例子 源码由七彩花都论坛提供 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &qu ...

  3. 算法笔记_010:插入排序(Java)

    1 问题描述 给定一组数据,使用插入排序得到这组数据的非降序排列. 2 解决方案 2.1 插入排序原理简介 引用自百度百科: 有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求 ...

  4. Some web Address

    1.可视化算法(Data Structure Visualizations) https://www.cs.usfca.edu/~galles/visualization/Algorithms.htm ...

  5. 关于AWS的备份策略

    AWS有一个很强大的功能,就是snapshot,翻译过来就是对EBS进行快照.通俗的说,即是对整个硬盘进行完整的镜像备份.如此一来,在其中一台EC2挂掉的时候,我们迅速的另起一台EC2,并将通过快照恢 ...

  6. Linux程序调试GDB——数据查看

    查看栈信息 当程序被停住了,首先要确认的就是程序是在哪儿被断住的.这个一般是通过查看调用栈信息来看的.在gdb中,查看调用栈的命令是backtrace,可以简写为bt. (gdb) bt    #0 ...

  7. 将textarea滚动至底部:

    var textarea = document.getElementById('id');textarea.scrollTop = textarea.scrollHeight;

  8. operator new 和 operator delete 实现一个简单内存泄漏跟踪器

    先来说下实现思路:可以实现一个Trace类,调用 operator new 的时候就将指向分配内存的指针.当前文件.当前行等信息添加进Trace 成员map容器内,在调用operator delete ...

  9. (一)Mina源代码解析之总体架构

    Apache Mina Server 是一个网络通信应用框架.也就是说,它主要是对基于TCP/IP.UDP/IP协议栈的通信框架(当然,也能够提供JAVA 对象的序列化服务.虚拟机管道通信服务等).M ...

  10. with(上下文的用法)以及其他知识点

    一.上下文 class Sxw(object): def __enter__(self): '''进入''' print("你好啊") def __exit__(self, exc ...