判断一个图是否有环无向图有向图讲解

合集下载

图论--图的基本概念

图论--图的基本概念

图论--图的基本概念1.图:1.1⽆向图的定义:⼀个⽆向图G是⼀个有序的⼆元组<V,E>,其中V是⼀个⾮空有穷集,称作顶点集,其元素称作顶点或结点。

E是⽆序积V&V的有穷多重⼦集,称作边集,其元素称作⽆向边,简称边。

注意:元素可以重复出现的集合称作多重集合。

某元素重复出现的次数称作该元素的重复度。

例如,在多重集合{a,a,b,b,b,c,d}中,a,b,c,d的重复度分别为2,3,1,1。

从多重集合的⾓度考虑,⽆元素重复出现的集合是各元素重复度均为1的多重集。

1.2有向图的定义:⼀个有向图G是⼀个有序的⼆元组<V,E>,其中V是⼀个⾮空有穷集,称作顶点集,其元素称作顶点或结点。

E是笛卡尔积V✖V的有穷多重⼦集,称作边集,其元素为有向边,简称为边。

通常⽤图形来表⽰⽆向图和有向图:⽤⼩圆圈(或实⼼点)表⽰顶点,⽤顶点之间的连线表⽰⽆向边,⽤带箭头的连线表⽰有向边。

与1.1,1.2有关的⼀些概念和定义:(1)⽆向图和有向图统称为图,但有时也把⽆向图简称作图。

通常⽤G表⽰⽆向图,D表⽰有向图,有时也⽤G泛指图(⽆向的或有向的)。

⽤V(G),E(G)分别表⽰G的顶点集和边集,|V(G)|,|E(G)|分别是G的顶点数和边数,有向图也有类似的符号。

(2)顶点数称作图的阶,n个顶点的图称作n阶图。

(3)⼀条边也没有的图称作零图,n阶零图记作N n。

1阶零图N1称作平凡图。

平凡图只有⼀个顶点,没有边。

(4)在图的定义中规定顶点集V为⾮空集,但在图的运算中可能产⽣顶点集为空集的运算结果,为此规定顶点集为空集的图为空图,并将空图记作Ø。

(5)当⽤图形表⽰图时,如果给每⼀个顶点和每⼀条边指定⼀个符号(字母或数字,当然字母还可以带下标),则称这样的图为标定图,否则称作⾮标定图。

(6)将有向图的各条有向边改成⽆向边后所得到的⽆向图称作这个有向图的基图。

(7)若两个顶点v i与v j之间有⼀条边连接,则称这两个顶点相邻。

图论知识点

图论知识点

图论知识点摘要:图论是数学的一个分支,它研究图的性质和应用。

图由节点(或顶点)和连接这些节点的边组成。

本文将概述图论的基本概念、类型、算法以及在各种领域的应用。

1. 基本概念1.1 节点和边图由一组节点(V)和一组边(E)组成,每条边连接两个节点。

边可以是有向的(指向一个方向)或无向的(双向连接)。

1.2 路径和环路径是节点的序列,其中每对连续节点由边连接。

环是一条起点和终点相同的路径。

1.3 度数节点的度数是与该节点相连的边的数量。

对于有向图,分为入度和出度。

1.4 子图子图是原图的一部分,包含原图的一些节点和连接这些节点的边。

2. 图的类型2.1 无向图和有向图无向图的边没有方向,有向图的每条边都有一个方向。

2.2 简单图和多重图简单图是没有多重边或自环的图。

多重图中,可以有多条边连接同一对节点。

2.3 连通图和非连通图在无向图中,如果从任意节点都可以到达其他所有节点,则称该图为连通的。

有向图的连通性称为强连通性。

2.4 树树是一种特殊的连通图,其中任意两个节点之间有且仅有一条路径。

3. 图的算法3.1 最短路径算法如Dijkstra算法和Bellman-Ford算法,用于在加权图中找到从单个源点到所有其他节点的最短路径。

3.2 最大流最小割定理Ford-Fulkerson算法用于解决网络流中的最大流问题。

3.3 匹配问题如匈牙利算法,用于解决二分图中的匹配问题。

4. 应用4.1 网络科学图论在网络科学中有广泛应用,如社交网络分析、互联网结构研究等。

4.2 运筹学在运筹学中,图论用于解决物流、交通网络优化等问题。

4.3 生物信息学在生物信息学中,图论用于分析蛋白质相互作用网络、基因调控网络等。

5. 结论图论是数学中一个非常重要和广泛应用的领域。

它不仅在理论上有着深刻的内涵,而且在实际应用中也发挥着关键作用。

随着科技的发展,图论在新的领域中的应用将会不断涌现。

本文提供了图论的基础知识点,包括概念、图的类型、算法和应用。

chap14 有向图

chap14 有向图
19
有向H图的应用
任务的最佳排序问题:假设有任务t1, t2, …tn需在
同一设备上串行执行,从任务ti转到任务tj所需的 设备调整时间是aij,如何排任务执行次序,使设 备调整需时间最少?
1、建图:建立有向图D, 顶点对应于要执行的任务,
vivjA(D)当且仅当aijaji。边vivj带权aij。
T的高度为3 ;
T中的蓝色结点及弧构成 T的一个以v2为根的子树.
27
有序树
定义14.3.3:若对一个树T的结点(弧)从
上至下,同一层结点(弧)从左至右规定了 一个次序,则称T为有序树。 v0 有序树的编号:
v1 v2 v3
v21
v211 v212
v22
v213
v31
28
m元(有序)树
定义14.3.4:设T是(有序)树,m 1。
3 v3
D D’
17
竞赛图
竞赛图:完全图的定向图称为竞赛图。
n阶竞赛图可用来表示n个选手之间进行
循环赛的胜负状态。
有一人全胜,其余各胜 一场: 有一人全输,其余各胜 两场:
18
竞赛图都含有向H通路
有向图D的有向H通路是指一条包含D的所有顶
点的有向通路(有向哈密尔顿通路)。 推论14.2.1:每个竞赛图都含有向H通路。 证明:设D是竞赛图, D的基础图G是完全图, 于是, (G) = |V(D)| =p , 由定理14.2.1知,D中含长为p–1的有向通路, 也就是说,该通路上包含了所有的p个顶点, 即为有向H通路。
3(a). D 中任何一条有向(u, v)-通路(u≠v)P均满足 (u)≠(v) 3(b). D 中的任何弧(u,v) v 1 的首尾不同色 2 4. 总之,基础图G的 任何两个邻接的顶 点在下均不同色, 4 即是G的正常(k+1) v2 着色。 故k≥ (G) –1

图论及其应用习题答案

图论及其应用习题答案

图论及其应用习题答案图论及其应用习题答案图论是数学的一个分支,研究的是图的性质和图之间的关系。

图是由节点和边组成的,节点表示对象,边表示对象之间的关系。

图论在计算机科学、电子工程、物理学等领域有着广泛的应用。

下面是一些图论习题的解答,希望对读者有所帮助。

1. 问题:给定一个无向图G,求图中的最大连通子图的节点数。

解答:最大连通子图的节点数等于图中的连通分量个数。

连通分量是指在图中,任意两个节点之间存在路径相连。

我们可以使用深度优先搜索(DFS)或广度优先搜索(BFS)来遍历图,统计连通分量的个数。

2. 问题:给定一个有向图G,判断是否存在从节点A到节点B的路径。

解答:我们可以使用深度优先搜索(DFS)或广度优先搜索(BFS)来遍历图,查找从节点A到节点B的路径。

如果能够找到一条路径,则存在从节点A到节点B的路径;否则,不存在。

3. 问题:给定一个有向图G,判断是否存在环。

解答:我们可以使用深度优先搜索(DFS)或广度优先搜索(BFS)来遍历图,同时记录遍历过程中的访问状态。

如果在搜索过程中遇到已经访问过的节点,则存在环;否则,不存在。

4. 问题:给定一个加权无向图G,求图中的最小生成树。

解答:最小生成树是指在无向图中,选择一部分边,使得这些边连接了图中的所有节点,并且总权重最小。

我们可以使用Prim算法或Kruskal算法来求解最小生成树。

5. 问题:给定一个有向图G,求图中的拓扑排序。

解答:拓扑排序是指将有向图中的节点线性排序,使得对于任意一条有向边(u, v),节点u在排序中出现在节点v之前。

我们可以使用深度优先搜索(DFS)或广度优先搜索(BFS)来遍历图,同时记录节点的访问顺序,得到拓扑排序。

6. 问题:给定一个加权有向图G和两个节点A、B,求从节点A到节点B的最短路径。

解答:我们可以使用Dijkstra算法或Bellman-Ford算法来求解从节点A到节点B的最短路径。

这些算法会根据边的权重来计算最短路径。

图(有向图、无向图)

图(有向图、无向图)

图(有向图、⽆向图)⼀、图的概念1 .图的定义图 1.3-1所⽰的⑴,⑵,⑶均为图 (Graph),它有若⼲个不同的点 v 1, v 2, …, v n,在其中⼀些点之间⽤直线或曲线连接。

图中的这些点被称为顶点 (vertex)或结点,连接顶点的曲线或直线称为边 (edge)。

通常将这种由若⼲个顶点以及连接某些顶点的边所组成的图形称为图,顶点通常被称作是图中的数据元素。

图1.3-1在线性结构中每个元素只有⼀个前趋和⼀个后续,⽽图1.3-1中的各个图则与之不同,它是⼀种较为复杂的⾮线性数据结构,在图结构中的任意两个元素之间都可能相互联系,即每个元素都可能有多个前趋或多个后续。

图作为⼀种数据结构,通常⼜可被定义为: graph=(V, E)或G=(V,E),即⼀个图是由顶点的集合 V和边的集合 E组成组成。

在图 1.3-1中⑴图中的边没有⽅向,这类图称为⽆向图 (undirected graph)。

在记录⽆向图时, (v 1, v 2 )等价于 (v 2, v 1)。

在图 1.3-1中⑵图中的边上有⼀个箭头,它表⽰边的⽅向,这类图称为有向图 (directed graph)。

在记录有向图时, <v 1, v 2 >与 <v 2, v 1 >是两条不同的边。

图 1.3-1中⑴图的顶点集合为:V ={ v 1, v 2, v 3, v 4}边集合为:E ={( v 1, v 2),( v 1, v 3),( v 2, v 3),( v 2, v 4),( v 3, v 4)}图 1.3-1中⑵图的顶点集合为:V ={ v 1, v 2, v 3, v 4}边集合为:E ={ <v 1, v 2 >, <v 1, v 3 >, <v 1, v 4 >, <v 2, v 1 >, <v 4, v 2 >}2 .图的常⽤术语环 (cycle):图 1.3-1中⑶图中的 v 1点本⾝也有边相连,这种边称为环。

13级离散数学(3-1图论)

13级离散数学(3-1图论)

【作业6】在一个部门的25个人中间,由于意见不
同,是否可能每个人恰好与其他5个人意见一致? 分析:考虑一个图,其中顶点代表人,如果两个人 意见相同,可用边连接,所以每个顶点都是5度。 解:令 25 个人分别为 v1 v2 …v25 . 则 degv1 = degv2 =…= degv25 =5 degv1 + degv2 +…+degv25 =125 是奇数 但在任何图中, 度数为奇数的结点必定是偶数, 所以是不可能的。
【作业5】求出下列各图的补图?
测试题
【测试题1】
a)画出无向完全图K4 和K6 并求出它们的边数。 b)画出完全二部图K4,2 ,和K3,3 并求出它们的边数。
【测试题2】
a)判断下列各图是否是(1)图的生成图、导出图或补图? b)画出(1)图的补图,并求出完全图K5的边数。
例:G1是无向图,deg(v1)=3,deg(v2)=1
G2是有向图,deg+(v1)=3,deg-(v1)=2,
deg(v1)=5,
v1 v2 v1
G2
v2
v3
G1
d(v1)=3(注意,环提供2
度), v2是悬挂顶点,
v4
【作业4】求下列各图顶点的度数
【注意】d-(a)=4,d+(a)=1
(环e1提供出度1,提供入度1) d(a)=4+1=5。
【说明】无向完全图:每一条边都是无向边不
含有平行边和环,每一对顶点间都有边相连。
完全图举例
K5
3阶有向完全图
4阶有向完全图
n阶无向完全图的边数为:
n(n-1)/2
【作业2】画出无向完全图K3 ,K4 和K6 并求出
它们的边数。

图的基本概念

第一章 图的基本概念第一节 图和有向图定义1.1 一个无向图图(graph )G 是指一个二元组),(E V ,其中集合V 中的元素称为顶点(或点,或端点, 或结点)(or vertice, or node, or point), 集合E 中元素为V 中元素组成的无序对,称为边 (edge).注意:1. 上述集合E 中的元素可以相同,有的文献称这样的集合为多重集。

2. 图),(∅∅称为空图,它有时在举反例的时候用到,且有时将一个结论推广到包含空图时会引起不必要的麻烦, 故本书中假设所讨论的图都不是空图。

3. 在一个图=G ),(E V 中,为了表示V 和E 分别是G 顶点集合边集,常将V 和E 分别记为)(G V 和)(G E .我们经常用图形来表示一个图。

用小圆圈或实心点表示图的顶点,用线段把无序对中两个顶点连接起来表示边。

其中顶点的位置,连线的曲直、是否相交等都无关紧要. 例如,=G ),(E V ,V =}{54321,,,,v v v v v ,=G }{),(),,(),,(),,(),,(),,(544231212111v v v v v v v v v v v v ,G 的图形如下.3v 4ve 2 5v1v 2v1e图. 1.设=G ),(E V . 若V 为有限集,则称G 为有限图(finite graph );若V 为单点集,则称G 为平凡图 (trivial graph ). 为方便起见,常用e i 表示边,例如在图1中2e 表示边),(31v v , 而1v ,3v 称为2e 的端点. 两个顶点相同的边称为环 (loop), 具有相同顶点的多条边称为重边 (multiple edge), 不含环和重边的图称为简单图 (simple graph). 例如在图1中1e 为环, 32,e e 为重边,所以此图不是简单图.定义1.2 设图G 的顶点集为)(G V ={}n v v v ,...,,21,边集为)(G E ={}m e e e ,...,,21.G 的邻接矩阵(adjacency matrix ))(G A 是一个n n ⨯矩阵,元素j i a ,为端点的边的数目。

图论中的圈与块,无向图的最小环


浙江省2006年集训讲义
29
嗅探器(4)
题目要求的点一定是图中的割点,但是图中 的割点不一定题目要求的点。如上图中的蓝 色点,它虽然是图中的割点,但是割掉它之 后却不能使a和b不连通 由于a点肯定不是我们所求的点,所以可以以 a为根开始DFS遍历整张图。 对于生成的DFS树,如果点v是割点,如果以 他为根的子树中存在点b,那么该点是问题所 求的点。
2011-1-28 浙江省2006年集训讲义 17
DFS算法
父子边用黑色标记,返祖边用红色标记 如下图,除掉返祖边之后,我们可以把它看 作一棵DFS树
1 2 3 4 5
6
7
2011-1-28
浙江省2006年集训讲义
18
割点
G是连通图,v∈V(G),G – v 不再连通,则称 v是G的割顶。
2011-1-28
结点个数N≤100000 边数M≤1000000
2011-1-28
浙江省2006年集训讲义
32
关键网线(2)
朴素算法: 枚举每条边,删除它,然后判断是否有独立 出来的连通区域内没有A属性或者没有B属性。 复杂度O(M2) 当然,这个复杂度太大了!
2011-1-28
浙江省2006年集训讲义
33
关键网线(3)
2011-1-28 浙江省2006年集训讲义 15
块及其相关知识
DFS算法 割点 (一般对于无向图而言) 割边 (一般对于无向图而言) 块(一般对于无向图而言) 强连通子图(一般对于有向图而言)
2011-1-28
浙江省2006年集训讲义
16
DFS算法
1973年,Hopcroft和Tarjan设计了一个有效的DFS算法 PROCEDURE DFS(v); begin inc(sign); dfn[v] := sign; //给v按照访问顺序的先后标号为sign for 寻找一个v的相邻节点u if 边uv没有被标记过 then begin 标记边uv; 给边定向v→u; 如果u被标记过,记uv为父子边,否则记uv为返祖边 if u未被标记 then DFS(u); end; end;

数据结构-图

回退到C,C 的4 个邻接顶点中还有D 和G 没有访问,选择一个顶点,例如以D 作为新的
出发点,访问D,标注数字序号④;
(a)无向图 G9
(b)深度优先遍历
图的遍历
3.1图的深度优先遍历
接着到G,访问G, 标注数字序号⑤;G 相邻顶点都访问过了,顺着虚线箭头方向
回退到 D,D 相邻顶点都访问过了,顺着虚线箭头方向回退到C,C 相邻顶点也都访问过
图的基本概念
1.2图的操作定义
02
PART
图的存储结构
2.1邻接矩阵
首先介绍的是数组表示法,即用两个数组分别存储顶点的信息和顶点之间的关系。
用来存放图中 n 个顶点的数组称为顶点数组。我们可将图中顶点按任意顺序保存到顶点数组中,
这样按存放次序每个顶点就对应一个位置序号(简称位序),依次为0~n-1;接着用一个 n×n 的二维
称为有向图。例如,当V={v1,v2,v3,v4,v5},VR={<v1,v2>,
<v1,v4>,<v2,v4>,<v3,v1>,<v3,v5>,<v4,v3>,<v5,v4>},则顶点集合
V、关系集合VR 构成有向图G1=(V,VR),如图(a)所示。
图的基本概念
1.1图的定义与基本术语
无向图(Undirected Graph)。如果顶点间的关系是无
序号作为表结点的值,所以一条弧对应一个表结点。右图为有向图 G1
和无向图 G2的邻接表表示法存储示意图。
图的存储结构
2.2邻接表
对于有向网和无向网,由于表结点表示边或弧,因此需要对表结点扩充一个属性域,表
结点至少包含顶点序号、权值和下一表结点指针 3 个属性,由此构成网的邻接表。

5.图论


注意:在无向图中,无向边(a,b)是从顶点a到顶点b的 线段,无方向.在有向图中,有向边<a,b>是有方向的, 且箭头必须从a指向b.也常用e=<vi,vj>表示边.有时 用G泛指无向图或有向图,而D只能表示有向图. 几个概念: 设G=<V,E>为一无向图或有向图, (1)若V,E都是有穷集合,则称G是有限图. (2)若|V|=n,则称G为n阶图.(此处|V|表示V中元素个 数;这里n≥1) (3)若E=,则称G为零图(仅包含孤立结点的图).特别 的,若此时又有|V|=1,则称G为平凡图(只有一个结点 的图).
第三部分 图论
在计算机科学领域,如开关理论,逻辑设 计,形式语言,操作系统,编译程序,数据结 构和信息检索等,都以图论为工具来解决实 际问题和理论问题,图论有着广泛的应用. 图论的内容十分丰富,涉及面也比较广, 本部分所涉及的只是图论中最基本的,但在 实际中经常用到的知识.
第7章 图的基本概念
7.1 无向图和有向图
定义 一个无向图G是一个二元组<V,E>, 即 G=<V,E>,其中
(1)V是一个非空的集合(在图的运算中,有时产生 顶点集合为的结果,因而规定顶点集为的图 是无意义的),称为G的顶点集,V中元素称为顶 点或结点. (2)E是无序积V&V的一个多重子集(元素可重复出 现的集合为多重集),E中元素称为无向边,也简 称边. 在一个图G=<V,E>中,为了表示V和E分别为G的顶 点集和边集,常将V记成V(G),E记成E(G).
在上图中,(2),(3)均为(1)的子图,(3)是生成图,(2) 是顶点集{v1,v2}的导出子图,也是边子集{e4,e5}的 导出子图.(3)是边子集{e1,e3,e4}的导出子图. (5),(6)是(4)的子图,(5)是生成子图,也是边子集 {e1,e2}的导出子图.(6)边子集{e1}的导出子图.
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、无向图:方法1:如果存在回路,则必存在一个子图,是一个环路。

环路中所有顶点的度〉=2。

n算法:第一步:删除所有度<=1的顶点及相关的边,并将另外与这些边相关的其它顶点的度减一。

第二步:将度数变为1的顶点排入队列,并从该队列中取出一个顶点重复步骤一。

如果最后还有未删除顶点,则存在环,否则没有环。

n算法分析:由于有m条边,n个顶点。

i)如果m〉=n,则根据图论知识可直接判断存在环路。

(证明:如果没有环路,则该图必然是k棵树 k>=1.根据树的性质,边的数目m = n-k.k〉=1,所以:m<n)ii)如果m〈n 则按照上面的算法每删除一个度为0的顶点操作一次(最多n次),或每删除一个度为1的顶点(同时删一条边)操作一次(最多m次).这两种操作的总数不会超过m+n。

由于m〈n,所以算法复杂度为O(n).注:该方法,算法复杂度不止O(V),首先初始时刻统计所有顶点的度的时候,复杂度为(V + E),即使在后来的循环中E>=V,这样算法的复杂度也只能为O(V + E)。

其次,在每次循环时,删除度为1的顶点,那么就必须将与这个顶点相连的点的度减一,并且执行delete node from list[list[node]],这里查找的复杂度为list[list[node]]的长度,只有这样才能保证当degree[i]=1时,list[i]里面只有一个点。

这样最差的复杂度就为O(EV)了.方法2:DFS搜索图,图中的边只可能是树边或反向边,一旦发现反向边,则表明存在环。

该算法的复杂度为O(V).方法3:摘自:http:///lzrzhao/archive/2008/03/13/2175787。

aspxPS:此方法于2011—6-12补充假定:图顶点个数为M,边条数为E遍历一遍,判断图分为几部分(假定为P部分,即图有 P 个连通分量)对于每一个连通分量,如果无环则只能是树,即:边数=结点数-1只要有一个满足边数 > 结点数-1原图就有环将P个连通分量的不等式相加,就得到:P1:E1=M1-1P2:E2=M2—1.。

.PN:EN>MN—1所有边数(E) 〉所有结点数(M)—连通分量个数(P)即: E + P > M 所以只要判断结果 E + P 〉M 就表示原图有环,否则无环.实例代码如下:1.#include〈iostream〉2.#include〈malloc.h〉ing namespace std;4.#define maxNum 100 //定义邻接举证的最大定点数5.int visited[maxNum];//通过visited数组来标记这个顶点是否被访问过,0表示未被访问,1表示被访问6.int DFS_Count;//连通部件个数,用于测试无向图是否连通,DFS_Count=1表示只有一个连通部件,所以整个无向图是连通的7.int pre[maxNum];8.int post[maxNum];9.int point;//pre和post的值10.11.//图的邻接矩阵表示结构12.typedef struct13.{14.char v[maxNum];//图的顶点信息15.int e[maxNum][maxNum];//图的顶点信息16.int vNum;//顶点个数17.int eNum;//边的个数18.}graph;19.void createGraph(graph *g);//创建图g20.void DFS(graph *g);//深度优先遍历图g21.void dfs(graph *g,int i);//从顶点i开始深度优先遍历与其相邻的点22.void dfs(graph *g,int i)23.{24.//cout<<"顶点”<<g—〉v[i]<<”已经被访问"〈<endl;25.cout〈〈"顶点”<<i<<"已经被访问”〈〈endl;26.visited[i]=1;//标记顶点i被访问27.pre[i]=++point;28.for(int j=1;j〈=g-〉vNum;j++)29.{30.if(g-〉e[i][j]!=0&&visited[j]==0)31.dfs(g,j);32.}33.post[i]=++point;34.}35.36.void DFS(graph *g)37.{38.int i;39.//初始化visited数组,表示一开始所有顶点都未被访问过40.for(i=1;i〈=g-〉vNum;i++)41.{42.visited[i]=0;43.pre[i]=0;44.post[i]=0;45.}46.//初始化pre和post47.point=0;48.//初始化连通部件数为049.DFS_Count=0;50.//深度优先搜索51.for(i=1;i〈=g—〉vNum;i++)52.{53.if(visited[i]==0)//如果这个顶点为被访问过,则从i顶点出发进行深度优先遍历54.{55.DFS_Count++;//统计调用void dfs(graph *g,int i);的次数56.dfs(g,i);57.}58.}59.}60.void createGraph(graph *g)//创建图g61.{62.cout〈〈”正在创建无向图..."<〈endl;63.cout<<"请输入顶点个数vNum:";64.cin>〉g-〉vNum;65.cout〈<"请输入边的个数eNum:”;66.cin〉>g->eNum;67.int i,j;68.//输入顶点信息69.//cout<〈"请输入顶点信息:"<<endl;70.//for(i=0;i〈g->vNum;i++)71.// cin〉〉g-〉v[i];72.//初始画图g73.for(i=1;i〈=g->vNum;i++)74.for(j=1;j<=g—>vNum;j++)75.g->e[i][j]=0;76.//输入边的情况77.cout〈<”请输入边的头和尾”<〈endl;78.for(int k=0;k<g—〉eNum;k++)79.{80.cin〉〉i>〉j;81.g->e[i][j]=1;82.g-〉e[j][i]=1;//无向图对称83.}84.}85.int main()86.{87.graph *g;88.g=(graph*)malloc(sizeof(graph));89.createGraph(g);//创建图g90.DFS(g);//深度优先遍历91.//连通部件数,用于判断是否连通图92.cout〈<"连通部件数量:”;93.cout〈<DFS_Count〈<endl;94.if(DFS_Count==1)95.cout<〈"图g是连通图”〈<endl;96.else if(DFS_Count〉1)97.cout〈〈"图g不是连通图”〈〈endl;98.//各顶点的pre和post值99.for(int i=1;i<=g—>vNum;i++)100.cout<〈”顶点"<<i〈<”的pre和post分别为:"〈〈pre[i]〈<" "〈<post[i]<〈endl;101.//cout<〈endl;102.//判断无向图中是否有环103.if(g—>eNum+DFS_Count>g-〉vNum)104.cout〈〈”图g中存在环”〈〈endl;105.else106.cout<〈"图g中不存在环"<〈endl;107.int k;108.cin〉〉k;109.return0;110.}111./*112.输入:113.正在创建无向图.。

114.请输入顶点个数vNum:10115.请输入边的个数eNum:9116.请输入边的头和尾117.1 2118.1 4119.2 5120.2 6121.4 7122.5 9123.6 3124.7 8125.9 10126.*/注意:有向图不能使用此方法。

比如1->2,1—3,2—〉3,4->5,如果使用上述方法会判定为含有还,但并非如此。

二、有向图:主要有深度优先和拓扑排序2中方法1、拓扑排序,如果能够用拓扑排序完成对图中所有节点的排序的话,就说明这个图中没有环,而如果不能完成,则说明有环。

2、可以用Strongly Connected Components来做,我们可以回忆一下强连通子图的概念,就是说对于一个图的某个子图,该子图中的任意u-〉v,必有v->u,则这是一个强连通子图。

这个限定正好是环的概念。

所以我想,通过寻找图的强连通子图的方法应该可以找出一个图中到底有没有环、有几个环。

3、就是用一个改进的DFS刚看到这个问题的时候,我想单纯用DFS就可以解决问题了。

但细想一下,是不能够的。

如果题目给出的是一个无向图,那么OK,DFS是可以解决的。

但无向图得不出正确结果的。

比如:A->B,A-〉C—〉B,我们用DFS来处理这个图,我们会得出它有环,但其实没有。

我们可以对DFS稍加变化,来解决这个问题。

解决的方法如下:图中的一个节点,根据其C[N]的值,有三种状态:0,此节点没有被访问过-1,被访问过至少1次,其后代节点正在被访问中1,其后代节点都被访问过。

按照这样的假设,当按照DFS进行搜索时,碰到一个节点时有三种可能:1、如果C[V]=0,这是一个新的节点,不做处理2、如果C[V]=—1,说明是在访问该节点的后代的过程中访问到该节点本身,则图中有环。

3、如果C[V]=1,类似于2的推导,没有环. 在程序中加上一些特殊的处理,即可以找出图中有几个环,并记录每个环的路径PS:此代码实现于2011—6-13补充改进DFS算法代码示例(判断是否是一个有向无环图)1.#include<iostream〉2.#include〈malloc。

h>ing namespace std;4.#define maxNum 100 //定义邻接举证的最大定点数5.int pre[maxNum];6.int post[maxNum];7.int point=0;//pre和post的值8.bool is_DAG=true;//标识位,表示有向无环图9./*10.顶点颜色表color[u]11.0 白色,未被访问过的节点标白色12.-1 灰色,已经被访问过一次的节点标灰色13. 1 黑色,当该节点的所有后代都被访问过标黑色14.反向边:15.如果第一次访问(u,v)时v为灰色,则(u,v)为反向边.在对图的深度优先搜索中没有发现16.反向边,则该图没有回路17.程序判断依据:18.仍然是按图的节点深度遍历,访问到V时,V若被访问过,那么有2种状态:19.color[u]=—1,程序跳出,存在环20.color[u]=1,程序继续,这不是环21.时间复杂度:O(n+e)22.*/23.int color[maxNum];//顶点颜色表color[u]24.//图的邻接矩阵表示结构25.typedef struct26.{27.char v[maxNum];//图的顶点信息28.int e[maxNum][maxNum];//图的顶点信息29.int vNum;//顶点个数30.int eNum;//边的个数31.}graph;32.void createGraph(graph *g);//创建图g33.void DFS(graph *g);//深度优先遍历图g34.void dfs(graph *g,int i);//从顶点i开始深度优先遍历与其相邻的点35.void dfs(graph *g,int i)36.{37.//cout〈〈"顶点"〈〈g-〉v[i]〈<"已经被访问”<〈endl;38.cout〈<”顶点”<<i〈〈"已经被访问"〈<endl;39.color[i]=—1;40.pre[i]=++point;41.for(int j=1;j<=g-〉vNum;j++)42.{43.if(g->e[i][j]!=0)44.{45.if(color[j]==—1)//探索到回边,存在环46.{47.is_DAG=false;//不是有向无环图48.}49.else if(color[j]==0)50.dfs(g,j);51.}52.}53.post[i]=++point;54.color[i]=1;//表示i的后裔节点都被访问过55.}56.void DFS(graph *g)57.{58.int i;59.//初始化color数组,表示一开始所有顶点都未被访问过,//初始化pre和post。

相关文档
最新文档