判断有向图是否有环

判断一个有向图是否有环 Description 给出一个有向图,判断图中是否存在回路。 Input 第1行:输入图的顶点个数N(1 ≤ N≤ 2,500)和C(图的边数,1 ≤ C ≤ 6,200); 第2到C+1行中,第i+1行输入两个整数,分别表示第i条边的起点和终点的编号。 Output 如果图中存在回路,输出“YES”,否则,输出“NO”。 Sample Input 7 阅读详情

第一种方法:拓扑排序

对于有向图的拓扑排序,大家都知道的kahn算法:

  1. 计算图中所有点的入度,把入度为0的点加入栈
  1. 如果栈非空:
  1. 如果图中还存在顶点,则表示图中存在环;否则输出的顶点就是一个拓扑排序序列

  1. 取出栈顶顶点a,输出该顶点值,删除该顶点

    从图中删除所有以a为起始点的边,如果删除的边的另一个顶点入度为0,则把它入栈

如果利用上面的拓扑排序算法求环,可以判断是否有环,但是输出环时有点麻烦。因为并不是所有最后剩余的点都是环中的顶点,比如如下情况:

image

对这个图运行上面的算法,最后所有的节点都不会被删除,但是只有1 2 3是环中的点,4不是环中的节点。

第二种方法:深度遍历

深度优先遍历该图,如果在遍历的过程中,发现某个节点有一条边指向已经访问过的节点,并且这个已访问过的节点不是当前节点的父节点(这里的父节点表示dfs遍历顺序中的父节点),则表示存在环。但是我们不能仅仅使用一个bool数组来标志节点是否访问过。

代码如下:

按照节点标记为黑色的时间,越先标记为黑色,在拓扑序列中越靠后。我们在算法2的基础上加了一个栈来保存拓扑排序的结果,只有dfsVisit的最后一行有改动,该算法,可以完成拓扑排序,并且同时可以检测图中是否有环。(该算法思想和算法导论22.4节拓扑排序一样)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
stack< int > tuopu;
 
void  dfsVisit(vector<vector< int > >&graph, int  node, vector< int >&visit,
                vector< int >&father)
{
     int  n = graph.size();
     visit[node] = 1;
     //cout<<node<<"-\n";
     for ( int  i = 0; i < n; i++)
         if (i != node && graph[node][i] != INT_MAX)
         {
             if (visit[i] == 1 && i != father[node]) //找到一个环
             {
                 int  tmp = node;
                 cout<< "cycle: " ;
                 while (tmp != i)
                 {
                     cout<<tmp<< "->" ;
                     tmp = father[tmp];
                 }
                 cout<<tmp<<endl;
             }
             else  if (visit[i] == 0)
             {
                 father[i] = node;
                 dfsVisit(graph, i, visit, father);
             }
         }
     visit[node] = 2;
     tuopu.push(node);
}
 
void  dfs(vector<vector< int > >&graph)
{
     int  n = graph.size();
     vector< int > visit(n, 0); //visit按照算法导论22.3节分为三种状态
     vector< int > father(n, -1); // father[i] 记录遍历过程中i的父节点
     for ( int  i = 0; i < n; i++)
         if (visit[i] == 0)
             dfsVisit(graph, i, visit, father);
}

 第三种方法:

根据有向图的强连通分量算法,每个强连通分量中必定存在环,因为根据强连通分量的定义:从顶点 i 到 j 有一条路径,并且从 j 到 i 也有一条路径。求强连通分量的算法可以参考维基百科

转自:http://www.cnblogs.com/TenosDoIt/p/3644225.html


两种方式判断有向图是否有环-python实现 两种方式判断有向图是否有环-python实现 1. DFS判断有向图是否有环 假设图以邻接矩阵表示,一条深度遍历路线中如果有结点被第二次访问到,那么有环。我们用一个变量来标记某结点的访问状态(未访问,访问过,其后结点都被访问过),然后判断每一个结点的深度遍历路线即可。 def dfs(G,i,color): r = len(G) color[i] = -1 have_cir... 阅读详情

相关推荐

在有向图中找出所有简单环--Johnson算法

本文简要介绍Johnson的在有向图中寻找简单化的算法。

Azeroit的博客 1万+

判断有向图是否有环 、环的个数以及环中元素

判断有向图是否有环有三种方法:拓扑排序、深度遍历+回溯、深度遍历 + 判断后退边 这里使用 拓扑排序 和 深度遍历 + 回溯判断是不是环。使用 深度遍历 + 判断后退边找出环个数 以及环中元素 1、拓扑排序 思想:找入度为0的顶点,输出顶点,删除出边。循环到无顶点输出。 若:输出所有顶点,则课拓扑排序,无环;反之,则不能拓扑排序,有环 使用:可以使用拓扑排序为有向无环图每一个结点进行编号,拓扑排序输出的顺序可以为编号顺序 源代码: [cpp] view plain copy #include <io

qq_38168462的博客 9426

Python 判断 有向图 是否有环

import numpy from numpy import * def dfs( v ): vis[v] = -1 flag = 0 for i in range(n): # print (a[v][i],'---', vis[i] ) if a[v][i] != 0 and vis[i] != -1: dfs(i

Xiaoyu Mo 7206

什么方法可以判断出一个有向图是否有环

一种常用的方法是使用拓扑排序。拓扑排序是一种对有向无环图(DAG)进行排序的算法,将所有顶点排序为一个线性序列,使得对于图中的任意一条边(u, v),节点u都出现在节点v之前。如果一个有向图不是DAG,则它一定有环。所以,对于给定的有向图,如果它能够成功地执行拓扑排序,则它是DAG,也就是说它没有环。 另一种方法是使用基于深度优先搜索的算法,如果在搜索过程中发现了已经访问过的节点,则表明图中有环。...

weixin_35756624的博客 2515

java用广度优先的方法来判断有向图是否有环

这里的代码参考了很多别人的代码和文章。。 今天师兄做笔试题,我也跟着看,碰到了一个要构建有向图并判断节点是否有环的题。 另一位师兄说这个题可以用并查集做,并且做出来了,我用并查集试了试做不出来。。 我觉得这题大概是要用有向图做,考察有向图的构建及寻找有向环 但是我只会对着书本抄代码构建有向图,不会寻找环,就尝试了一下用前不久做爬虫用到的广度遍历来寻找有向环。。

跳币上山岭的博客 2768

判断有向图是否有环的C程序实现代码

//主要思想是进行拓扑排序,如果所有定点都能排序,则无环,否则,有环 #include #include #include //该结构体用来表示从某个顶点可以到达的其他顶点 struct ENode {     int secPoint;//顶点号

冒大烟的羊肉串的专栏 2523

java判断有向图是否有环_判断有向图是否有环

方法一:拓扑排序时间复杂度O(n^2)比较常用的是用拓扑排序来判断有向图中是否存在环。什么是拓扑排序呢?我们先定义一条u到v的边e=,u生成拓扑序列的算法就叫拓扑排序啦~算法流程描述while(节点个数次(N)循环)1.找出入度为0的节点u(节点个数次(N)循环)2.删去这个节点u和从这个节点出发相连的边(,....,),更新这些边连的点(v1,v2,v3....vn)的入度信息。3.直到找不到入...

weixin_42131013的博客 2713

查找有向图中的环

有向图:主要有深度优先和拓扑排序2中方法1、拓扑排序,如果能够用拓扑排序完成对图中所有节点的排序的话,就说明这个图中没有环,而如果不能完成,则说明有环。2、可以用Strongly Connected Components来做,我们可以回忆一下强连通子图的概念,就是说对于一个图的某个子图,该子图中的任意u->v,必有v->u,则这是一个强连通子图。这个限定正好是环的概念。所以我想,通过寻找图的强连通子

skysys的研究小屋 4472

判断无向图/有向图中是否存在环

本文主要针对如何判断有向图/无向图中是否存在环的问题进行简单的论述。 一 无向图 1.利用DFS进行判断 利用DFS判断有向图是否存在环,是最为常用的一种方法,虽然这种方法很常用,但可参考的代码的实现比较少,下面对这种方法及其实现进行详细的阐述。 首先,利用DFS判断无向图中是否换的原理是:若在深度优先搜索的过程中遇到回边(即指向已经访问过的顶点的边),则必定存在环。 所以说,是否存在环...

lattice的博客 9925

拓扑排序(还实现了有向图找环)

用邻接矩阵实现的拓扑排序,如果不是DAG,会找出有向图中的一个环(NKU算法作业)

mcgs数据查表功能,用于大量数据对比查找对应数据,减少PLC代码

mcgs脚本实现数据查表功能

qq_24866535的博客 3270

判断有向图是否有环 [No. 75]

要判断一个有向图是否有环,我们可以选择选择BFS, DFS 或者 Topological sorting. 用BFS或者DFS进行判断时,我们主要判断要被访问的node是否已经被访问过,如果被访问过,就有环。利用topological sorting进行判断的时候,就是判断node是否只有一个node和它连接(算法第八行)(按照树的说法,也就是看那个点是否只有一个父节点)。 代码如下(来自wik

Yuwen's Hero 3493

零基础教程:用Python给试卷照片自动切题(有道OCR+PIL完整流程)

本文为零基础用户提供了一套完整的Python自动化切题方案。通过调用有道OCR API识别试卷照片中的题目坐标,并利用PIL库进行精准裁剪,将杂乱的试卷图片自动分割为独立的题目图像。教程详细涵盖了环境搭建、图像预处理、API调用、坐标解析与批量处理全流程,帮助教育工作者和技术爱好者高效处理大量试卷,实现工作流程自动化。

grpc6streamer的博客 1174

python有向图是否有环_判断无向图/有向图中是否存在环

本文主要针对如何判断有向图/无向图中是否存在环的问题进行简单的论述。一 无向图1.利用DFS进行判断利用DFS判断有向图是否存在环,是最为常用的一种方法,虽然这种方法很常用,但可参考的代码的实现比较少,下面对这种方法及其实现进行详细的阐述。首先,利用DFS判断无向图中是否换的原理是:若在深度优先搜索的过程中遇到回边(即指向已经访问过的顶点的边),则必定存在环。所以说,是否存在环的关键在于是否存在满...

weixin_35411487的博客 1556

PSOC Creator 入门教程超详细

最近工作原因需要使用到赛普拉斯的一款芯片,奈何以前没有用过,所以趁这次也学习了一些简单的用法,总结一下,希望能帮到有需要朋友,因为网上关于这方面的文章少的可怜,详细点的更是少之又少!废话少说,正文开始.

qm_mq的博客 5746

Avellaneda & Stoikov’s market-making strategy 工程化处理

前2篇文章详细介绍了AS存货模型的做市策略,这次对于这些公式里面一些希腊字母的取值是如何计算的,如何做工程化并应用到生产环境中做一些说明。这个里面有一些重要参数:很直观,可以直接取值的有:s = current market mid price (中间价,也就是【最佳卖价+最佳买价】/2)q = quantity of assets in inventory of base asset (也就是买入多少价值的股票数量)

weixin_42480337的博客 7068

有向图的DFS遍历及判断是否有环

#include <iostream> #include <cstdio> #include <vector> #include <cstring> #include <string> #include <algorithm> using namespace std; const int MAX = 1000; int color[MAX]; int Time; bool is_DAG; // 分别是时间撮,是否有环 int f..

weixin_42864519的博客 2754

Microsemi Libero使用技巧11——CoreUARTAPB RX管脚分配时不显示

调用串口IP核CoreUARTAPB,并例化到顶层设计,发现UART_RX管脚在进行管脚分配时没有显示出来,最后发现是CoreAPB3总线IP核配置不对导致,改为如下配置后正常。

whik1194的博客 757
上一篇: 图的深度优先搜索
下一篇: 堆排序之“用最小堆将k个已排序链表合并为一个排序链表”
Stephan14
博客等级 码龄13年 53粉丝 133原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值