【图论课件】第二课时·图的遍历
图的遍历和连通性
• 如果使用邻接表来表示图,则BFS循环的总时间代价为 d0 + d1 + … + dn-1 = O(e),其中的 di 是顶点 i 的度。
其算法也不是递归的。
• void BFSTraverse(Graph G, Status (*Visit)(int v)){
• for (v=0; v<G.vexnum; ++v)
•
visited[v] = FALSE; //初始化访问标志
• InitQueue(Q); // 置空的辅助队列Q
• for ( v=0; v<G.vexnum; ++v )
•(2)如何避免重复访问某个顶点?
•答:创建一个一维数组visited[0..n-1](n是图中顶 点的数目),用来记录每个顶点是否已经被访问过。
•(3)广度优先搜索有回退的情况吗?
1•
•答:广度优先搜索是一种分层的搜索过程,每向前走
一步可能访问一批顶点,不像深度优先搜索那样有回
退的情况。因此广度优先搜索不是一个递归的过程,
•}
7•
DFS 算法效率分析:
(设图中有 n 个顶点,e 条边)
(1)如果用邻接矩阵来表示图,遍历图中每一 个顶点都要从头扫描该顶点所在行,因此遍历全 部顶点所需的时间为O(n2)。
(2)如果用邻接表来表示图,虽然有 2e 个表结 点,但只需扫描 e 个结点即可完成遍历,加上访 问 n个头结点的时间,因此遍历图的时间复杂度 为O(n+e)。
• 若此时图中尚有顶点未被访问,则另选图中一个未曾 被访问的顶点作起始点,重复上述过程,直至图中 所有顶点都被访问到为止。
9•
图的遍历
的没被访问的邻接点,然后,分别从这些邻接点出发,广度优 的没被访问的邻接点,然后,分别从这些邻接点出发, 先遍历图,直至所有顶点都被访问; 先遍历图,直至所有顶点都被访问;若此时图中仍有结点没有 被访问,则另选图中一个未曾访问的顶点作起始点, 被访问,则另选图中一个未曾访问的顶点作起始点,重复上述 过程。 过程。
图的结构定义(邻接表) 图的结构定义
typedef struct ArcNode { int adjvex; struct ArcNode *nextarc; } ArcNode;
typedef struct VNode { VertexType data; ArcNode *firstarc; } VNode, AdjList[MAX_VERTEX_NUM];
方法:从图中的某一个顶点 v0 出发,访问此顶点,然后 依次从 出发,访问此顶点, 方法:
v0 的没被访问的邻接点出发深度优先遍历图,直至图中所有和 的没被访问的邻接点出发深度优先遍历图, v0 有路径相通的顶点都被访问到;若此时图中仍有结点没有被访 有路径相通的顶点都被访问到; 问,则另选图中一个未曾访问的顶点作起始点,重复上述过程。 则另选图中一个未曾访问的顶点作起始点,重复上述过程。
例如: 例如
0 1
a a b
4 5 6
b g
g f d
c h k f e
8
2
3
c
7
d h
0
e
8
k
1 2 3 4 5 6 7
访问标志: T T T T T T T T T 访问标志: F F F F F F F F F 访问次序: 访问次序: a c h d k f e b g
图的遍历
6
8 4 2 1
3.1 深度优先搜索遍历
1 2 4 5 8
1
栈
3 6 7
非递归
2
4
3
5
8
6
6 8 4 2 1
3.1 深度优先搜索遍历
1 2 4 5 8
1
栈
3 6 7
非递归
2
4
3
5
8
6
7
3 6 8 4 2 1
3.1 深度优先搜索遍历
1 2 4 5 8
1
栈
3 6 7
非递归
2
4
3
5
8
6
7
7的邻接 表空, 逐一退 栈
问过为止。
1 2 4 5 8 3 6 7
深度优先
1
2
4
3
所有都访 问完毕了
5
8
6
7
2已经访问返 回8
3.1 深度优先搜索遍历
下面以下图为例来讨论dfs算法的执行过程:调用dfs(1)
此箭头表示是从遍历运 算 dfs(1) 中调用 dfs(2) , 即从顶点1直接转到2
此虚箭头表示是在 dfs(3) 执行完毕后返回到遍历 运算 dfs(2) 中,即从顶点 3返回到2
1
2 3
以3为起点根本 不能遍历整个图
1
2
4
2
1 3
4 7 9 8
24
10
3
5
6
5
6
3.1 深度优先搜索遍历
3. 深度遍历算法的应用
问题: (1)如何设计算法以判断给定的无向图是否是连通的? (2)如何设计算法以求解给定的无向图中的边数? (3)设计算法以判断给定的无向图是树。 (4)设计算法以判断给定的有向图是以v0为根的有向树。 (5)设计算法以判断图中的一个节点是否为关节点。
图的遍历演示
inputt.close();
}
}
三、实验结果:
1.输入图
2. 遍历图:(先深度,后广度)
四、结果分析:
数据结构顾名思义讲求的是一种存储结构,一路走来先后学习了表、树,最后学习的是图,对于每种存储结构学习之初都会学习一些基本操作,而操作之中又以创建和遍历为最基本的操作,只有熟练掌握了以后才能对其他操作进行研究和学习。
在这次实验中,我也得到了很多收获,比如链表的应用,以前弄不太明白,通过这次实验,在链表这一方面我懂了很多,虽然还不能运用自如,但在这次实验中,对本学期所学习的内容也是一次巩固,让我加深了对学过知识的记忆。
总之,这次实验让我既发现了自身的很多不足,又增长了很多知识。
2-图的遍历
数据结构与算法分析第1111章章 图图1图的遍历许多应用需要对图中的每个结点恰好访问一次.基于图的拓扑结构,以特定顺序依次访问图中各个顶点是很有用的.例如:–人工智能搜索–最短路径问题24图的遍历(2)为了保证访问所有顶点:void void graphTraverse(const graphTraverse(const graphTraverse(const Graph Graph Graph** G) { for (v=0; v<G->n(); v++) G-> G->setMark(v setMark(v setMark(v, UNVISITED); // Initialize , UNVISITED); // Initialize for (v=0; v<G->n(); v++) if (G-> if (G->getMark(v getMark(v getMark(v) == UNVISITED)) == UNVISITED) doTraverse(G doTraverse(G doTraverse(G, v);, v);}从图中某个顶点V0 出发,访问此顶点,然后依次从V的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和V0有路径相通的顶点都被访问到。
一、深度优先搜索遍历图连通图的深度优先搜索遍历5从上页的图解可见:1. 从深度优先搜索遍历连通图的过程类似于树的先根遍历;2. 如何判别V的邻接点是否被访问?解决的办法是:为每个顶点设立一个“访问标志”。
78深度优先搜索(2)Cost: Θ(|V | + |E |).9深度优先搜索 DFS(1)// // Depth first search Depth first search void DFS(Graph void DFS(Graph** G, G, int int int v) { v) { PreVisit(G PreVisit(G PreVisit(G, v); // Take action , v); // Take action G->G->setMark(v setMark(v setMark(v, VISITED);, VISITED); for ( for (int int int w=G->first(v); w<G->n();w=G->first(v); w<G->n(); w = G->next(v,w)) if (G-> if (G->getMark(w getMark(w getMark(w) == UNVISITED)) == UNVISITED) DFS(G, w); PostVisit(G PostVisit(G PostVisit(G, v); // Take action , v); // Take action }非连通图的深度优先搜索遍历首先将图中每个顶点的访问标志设为 FALSE, 之后搜索图中每个顶点,如果未被访问,则以该顶点为起始点,进行深度优先搜索遍历,否则继续检查下一顶点。
第七章图(2)图的遍历
第7章图(2)图的遍历 主讲:刘春学习目标① 掌握图的基本概念,包括图、有向图、无向图、完全图、 子图连通图、度、入度、初度、简单回路和环等基本概念 的定义。
② 重点掌握图的各种存储结构、包括邻接矩阵和邻接表等 ③ 重点掌握图的基本元素、包括创建图、输出图、深度优先 遍历、广度优先遍历算法等 ④ 掌握图的其他运算、包括最小生成树、最短路径、拓扑排 序和关键路径等算法 ⑤ 灵活运用图这种数据结构解决 灵活运用图这种数据结构解决一些综合应用问题 些综合应用问题。
7.3 图的遍历图的遍历的定义 从图中某个顶点出发游历图,访遍图中其余顶点,并且使图中 的每个顶点仅被访问一次的过程。
1 2 4 5 6 3 7问题:图中可能存在回路,且图的任一顶点都 可能与其它顶点相通 在访问完某个顶点之后 可能与其它顶点相通,在访问完某个顶点之后 可能会沿着某些边又回到了曾经访问过的顶点。
为了避免重复访问,可设置一个标志辅助数组 visited[ ],它的初始状态为 0,在图的遍历过程 中,一旦某一个顶点 i 被访问,就立即让 visited[i]为 1,防止它被多次访问。
防止它被多次访问8根据搜索方法的不同,图的遍历有两种: 深度优先搜索(DFS)和广度优先搜素(WFS)。
7.3 图的遍历深度优先搜索( (Depth p _First Search) )主要思想:从图中某个顶点V0 出发,访问此顶点,然后选择一个 与V0邻接且未被访问的顶点W为初始顶点,再从W出发进行深度优 先搜索, 直至图中所有和V0有路径相通的顶点都被访问到; 若此时图中尚有顶点未被访问 则另选图中 个未曾被访问的顶点 若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点 作为起始点,重复上述过程,直至图中所有顶点都被访问到为止。
深度优先搜索是个递归的过程7.3 图的遍历连通图DFS的具体搜索过程: 在访问图中任意选某一起始顶点 v 后,由 v 出发,访问它的任一 邻接顶点 w1;再从 w1 出发,访问与 w1邻 接但还没有访问过的顶点 w2;然后再从 w2 出发,进行类似的访问,… 如此进行下去,直至 到达所有的邻接顶点都被访问过的顶点 u 为止。
图的两种图的遍历方法
5.3 图的遍历和树的遍历类似,在此,我们希望从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次。
这一过程就叫做图的遍历(TraversingGraph)。
图的遍历算法是求解图的连通性问题、拓扑排序和求关键路径等算法的基础。
然而,图的遍历要比树的遍历复杂得多。
因为图的任一顶点都可能和其余的顶点相邻接。
所以在访问了某个顶点之后,可能沿着某条路径搜索之后,又回到该顶点上。
[例如]图7.1(b)中的G2,由于图中存在回路,因此在访问了v1,v2,v3,v4之后,沿着边(v4 , v1)又可访问到v1。
为了避免同一顶点被访问多次,在遍历图的过程中,必须记下每个已访问过的顶点。
为此,我们可以设一个辅助数组visited[0..n-1],它的初始值置为“假”或者零,一旦访问了顶点vi,便置visited[i]为“真”或者为被访问时的次序号。
通常有两条遍历图的路径:深度优先搜索和广度优先搜索。
它们对无向图和有向图都适用。
5.3.1 深度优先搜索深度优先搜索(Depth-First Search)遍历类似于树的先根遍历,是树的先根遍历的推广。
其基本思想如下:假定以图中某个顶点vi为出发点,首先访问出发点,然后选择一个vi的未访问过的邻接点vj,以vj为新的出发点继续进行深度优先搜索,直至图中所有顶点都被访问过。
显然,这是一个递归的搜索过程。
现以图5-3-1中G为例说明深度优先搜索过程。
假定v0是出发点,首先访问v0。
因v0有两个邻接点v1、v2均末被访问过,可以选择v1作为新的出发点,访问v1之后,再找v1的末访问过的邻接点。
同v1邻接的有v0、v3和v4,其中v0已被访问过,而v3、v4尚未被访问过,可以选择v3作为新的出发点。
重复上述搜索过程,继续依次访问v7、v4 。
访问v4之后,由于与v4相邻的顶点均已被访问过,搜索退回到v7。
由于v7、v3和v1都是没有末被访问的邻接点,所以搜索过程连续地从v7退回到v3,再退回v1,最后退回到v0。
数据结构-图的遍历ppt
-
深度优先搜索-连通图
void DFS(Graph G, int v) {
// 从顶点v出发,深度优先搜索遍历连通图 G
visited[v] = TRUE; for(w=FirstAdjVex(G, v);
w>=0; w=NextAdjVex(G,v,w)) if (!visited[w]) DFS(G, w);
图的遍历
复习 图的遍历 深度优先搜索 广度优先搜索 课堂练习 小结和作业
-
复习-图的存储结构
B A
F
C D
E
010010 100011 000101 001001 110000 011100
-
复习-图的存储结构
B A
F
C D
E
0A
1B 2C 3D 4E 5F
1
4
0
4
5
3
5
2
5
0
1
1
2
3
-
复习-图的存储结构
}
-
邻接点函数的实现
int nextAdjVex(ALGragh G, int v, int w){ p=G.vertices[v].firstarc;//v的第1个邻接点 while(p && p->adjvex != w) p=p->nextarc; if(p) p = p->nextarc;//w之后的下一个邻接点 if(p) return p->adjvex; else return -1;}
// 对v的尚未访问的邻接顶点w递归调用DFS
} // DFS
余顶点,并且使图中的每个顶点仅被访问一次的过 程。
7图的遍历
数据结构
广度优先搜索算法
void BFSTraverse(Graph G, Status (* visit)(int v)) { for(v=0; v<G.vexnum; ++v) visited[v] = FALSE; IntiQueque(Q); for(v=0; v<G.vexnum; ++v) if(!visited[v]) { visited[v] = TRUE; Visit (v); EnQueue(Q,v); while(!QueueEmpty(Q)){ DeQueue(Q,u); for(w=FirstAdjVex(G, u);w;w = NextAdjVex(G,u,w)) if(!visited[w]) {visited[w]=TRUE; visited(w); EnQueue(G,w); } } } 7 数据结构 }
void DFSTree(Graph G,int v ,CSTree &T) { //从第 个顶点出发深度优先遍历图G 建立以T //从第v个顶点出发深度优先遍历图G,建立以T为根的生成 从第v 树 visited[v]=TRUE; first=TRUE; for(w=FirstAdjVex(G,v);w>=0; w=NextAdjVex(G,v,w)) if(!visited[w]) p=(CSTree)malloc(sizeof)CSNode));//分配孩子结点 { p=(CSTree)malloc(sizeof)CSNode));//分配孩子结点 *p={GetVex(G,w),NULL,NULL}; //w 的第一个未被访问的邻接顶点, if (first) //w是v的第一个未被访问的邻接顶点,作 为 根的左孩子结点 T{ T->lchild=p; first=FALSE; } //w 的其它未被访问的邻接顶点, else { //w是v的其它未被访问的邻接顶点,作为上一 邻 接顶点的右兄弟 q->nextsibling=p; } q=p; D 从第w //从第 DFSTree(G,w,q); //从第w个顶点出发深度优先遍历 A 图 G,建立生成子树q 建立生成子树q 12 数据结构 B C E }
《图论及其应用》课件
图像处理
探索图论在图像处理领域的应用,如图像分割 和模式识别。
七、总结
图论的重要性
强调图论在计算机科学和现实 世界中的重要性和广泛应用。
现实中的应用价值
讨论图论在实际问题中解决方 案的应用价值和优势。
对于未来的展望
探索图论在未来可能的发展方 向和应用领域,如人工智能和 物联网。
2
Floyd算法
介绍Floyd算法的原理和使用方法,用于计算图中所有节点之间的最短路径。
四、最小生成树算法
Prim算法
解释Prim算法的工作原理和应用,用于寻找图中的 最小生成树。
Kruskal算法
讨论Kruskal算法的概念和实现,用于生成图的最小 生成树。
五、网络流算法
1
最大流
介绍网络流问题和最大流算法,用于解
《图论及其应用》PPT课 件
本PPT课件将带您深入了解图论及其应用。图论是一门关于图的性质及其应用 的学科,将为您揭开图论的奥秘。
一、图论基础
图的定义及术语
介绍图的基本定义以及相关的术语,为后续内 容打下基础。
无向图与有向图
解释无向图和有向图的区别,并介绍它们之间 的关系和应用。
图的表示方法
讲解图的常用表示方法,如邻接矩阵和邻接表, 并比较它们的优缺点。
连通性和路径
讨论图的连通性概念以及如何找到两个节点之 间的最短路径。
二、图的遍历算法
1
广度优先搜索(BFS)
2
介绍广度优先搜索算法的工作原理和常 见应用。
深度优先搜索(DFS)
深入探讨深度优先搜索算法的原理和应 用场景。
三、最短路径算法
1
Dijkstra算法
详细讲解Dijkstra算法的步骤和应用,用于寻找图中两个节点间的最短路径。
图遍历算法
图遍历算法图遍历算法是一种基于图的搜索算法,用于从图中搜索指定的节点或路径。
图在计算机科学中是一种重要的数据结构,它可以用来表示一组复杂的关系。
图中的每个节点都是一个对象,而边则用来表示两个节点之间的关系。
图遍历算法类似于树遍历算法,其主要目的是从图中寻找某一节点或指定的路径。
图遍历算法的基本操作步骤1.图中的所有节点标记为未访问状态。
2. 从起始节点开始遍历,将当前节点标记为已访问状态。
3.查当前节点是否是目标节点,如果是则结束遍历,否则继续遍历。
4.查当前节点的相邻节点,如果有未访问的节点,则将其标记为已访问,并将其加入到待访问队列中。
5.复步骤3和步骤4,直到找到目标节点或遍历完整个图。
图遍历算法的应用场景图遍历算法主要用于图的搜索和路径查找。
它的应用场景有: 1.路算法:主要应用于地图导航、交通管理、机器人导航等场景,用于查找从指定的节点A到终点B的最优路径。
2.短路径算法:主要用于网络及其他复杂系统中,查找从起始节点到终点之间最短路径,也就是说,需要查找距离最短的路径,而不是按照一定顺序查找路径。
3.联分析算法:它是一种数据挖掘技术,用于挖掘分析大规模数据集合中被关联的结构和模式,包括聚类分析、关系挖掘、推荐系统等。
图遍历算法可以用于查找关联的数据,从而发现有益的模式和网络结构。
4.像处理:图像处理系统中,常常会使用图遍历算法来获取图像的各种特征,例如:特征提取、边缘检测、物体检测和分割等。
图遍历算法的性能图遍历算法的性能可以用时间复杂度和空间复杂度来表示,一般来说,图遍历算法的时间复杂度为 O(V+E)其中 V 为图中的节点数,E 为边的数目。
对于空间复杂度,一般会使用一个队列来保存待访问的节点,空间复杂度为 O(V) 。
总结图遍历算法是一种基于图的搜索算法,它主要用于搜索指定的节点或路径,并用于诸如寻路算法、最短路径算法、关联分析算法和图像处理等不同场景。
图遍历算法的时间复杂度为 O(V+E),空间复杂度为 O(V)因此,它适合于处理大型图,而不适用于小规模的图。
图的遍历
//访问(即打印)i号结点 // i
for (j=FirstAdjVex(G,i);j<> -1;j=NextAdjVex(G,i,j)) if (!visited[j]) DFS(G,j); //依次从i号顶点的第一个邻接点,
//第二个邻接点,...... 出发深度优先遍历图
}//DFS
一、深度优先遍历 号顶点的处于序号为j的邻接点的后面 求i号顶点的处于序号为 的邻接点的后面 号顶点的处于序号为
二、广度优先遍历
2.实例: 2.实例: 实例
v2
v3
v4
v5
v6
v7
v8
v9
v10
设从v1出发,则有遍历序列: v1 v2 v3 v4 v5 v6 v7 v8
v11
再从另一个连通子图中选择一个还未被访问的顶点v10, 并从v10出发重复上述过程有遍历序列:v10 v9 v11 从而有遍历序列:v1v2v3v4v5v6v7v8v10v9v11
void DFS (ALGraph G,int i){ visited[i]=TRUE; printf(G.vertices[i].data); //访问(即打印)i号结点 // i
for (j=FirstAdjVex(G,i);j<> -1;j=NextAdjVex(G,i,j)) if (!visited[j]) DFS(G,j); //依次从i号顶点的第一个邻接点,
一、深度优先遍历
3.算法: 3.算法: 算法 *主函数:
void DFStraverse(ALGraph G){ Boolean visited[G.vexnum]; for (i=0;i<G.vexnum;++i) visited[i]=FALSE; for (i=0;i<G.vexnum;++i) if (!visited[i]) DFS(G,i); }//DFStraverse
图的遍历和连通性共28页文档
6、纪律是自由的第一条件。——黑格 尔 7、纪律是集体的面貌,集体的声音, 集体的 动作, 集体的 表情, 集体的 信念。 ——马 卡连柯
8、我们现在必须完全保持党的纪律, 否则一 切都会 陷入污 泥中。 ——马 克思 9、学校没有纪律便如磨坊没有水。— —夸美 纽斯
10、一个人应该:活泼而守纪律,天 真而不 幼稚, 勇敢而 鲁莽, 倔强而 有原则 ,热情 而不冲 动,乐 观而不 盲目。 ——马 克思
56、书不仅是生活,而且是现在、过 去和未 来文化 生活的 源泉。 ——库 法耶夫 57、生命不可能有两次,但许多人连一 次也不 善于度 过。— —吕凯 特 58、问渠哪得清如许,为有源头活水来 。—— 朱熹 59、我的努力求学没有得到别的好处, 只不过 是愈来 愈发觉 自己的 无知。 ——笛 卡儿
拉
60、生活的道路一旦选定,就要勇敢地 走到底 ,决不 回头。 ——左
图的遍历演示
2.广度优先搜索(遍历)步骤: 广度优先搜索(遍历)步骤: 广度优先搜索
简单归纳: 简单归纳:
• • • 在访问了起始点v之后, 的邻接点; 在访问了起始点 之后,依次访问 v的邻接点; 之后 的邻接点 然后再依次访问这些顶点中未被访问过的邻接点; 然后再依次访问这些顶点中未被访问过的邻接点; 直到所有顶点都被访问过为止。 直到所有顶点都被访问过为止。 广度优先搜索是一种分层的搜索过程, 广度优先搜索是一种分层的搜索过程,每向前走一 步可能访问一批顶点, 步可能访问一批顶点,不像深度优先搜索那样有回 退的情况。因此, 退的情况。因此,广度优先搜索不是一个递归的过 其算法也不是递归的。 程,其算法也不是递归的。
可以用递归算法! 可以用递归算法 讨论2 讨论2: DFS算法如何编程? ——可以用递归算法! DFS算法如何编程? 算法如何编程
void ExtMGraph <T>::DFS (int v, void *visit()) , //设A[n][n]为邻接矩阵,v为起始顶点(编号) //设A[n][n]为邻接矩阵, 为起始顶点(编号) 为邻接矩阵 { visit(v); ( ) //访问 例如打印)顶点v 访问( //访问(例如打印)顶点v visited[v]=1; //访问后立即修改辅助数组标志 //访问后立即修改辅助数组标志 //从v所在行从头搜索邻接点 //从 所在行从头搜索邻接点 从头 for( j=0; j<n; j++) if ( A[v, j] && ! visited[j] ) DFS (j, visit); , return; 深度优先 visited [j ]=0 A[v,j] =1 } // DFS
借助于队列实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
大意:在一个神奇的图中,对于每个点所在 路径求最小环
Luogu P2921
在之前的基础上分析:首先不能按照联通 块求了,而要每个点分别求出最小环。 但是直接搜索显然太睿智,所以需要利用 算过的结果来优化。先画一张适用于大部分 情况的路径图。
Luogu P2921
出度为1,考虑利用路径的唯一性。除了 染色和时间戳,还可以将环外与环分类讨论。
Luogu P2661
图的遍历是O(n)的。用时间戳记录第一 次到达的时间(形象理解)。当遇到之前到 达过的点时,用当前时间-时间戳就得到了这 个环的大小。 遍历时染色以避免多次搜索。如果遇到之 前染过色的点(时间戳不为0的点),跳出。 (据说用并查集很简单)
Luogu P2921 [USACO08DEC]在农 场万圣节Trick or Treat on the Farm
大意:在一个神奇的图中找最小环大小。
Luogu P2661
这好像是个很弱的图——每个点出度皆为 1!正因为如此,每当选定一个起始点,就已 经确定了之后的所有路径。 这也导致了一个特点:从任意一个点出发, 总能够遍历这个点所属联通块(形象理解) 的最小环。该命题易证(滑稽)。 于是,现在问题就简化为分别在每个联通 块中求最小环。
课程小结
图的遍历一般使用DFS,少用BFS。 不重不漏地经过所有边是欧拉路,如果又 回到起点是欧拉回路。求解要注意细节。 时间戳可以在遍历时帮助计算大小。
环外优化:记录之后入环时间,记为ic。 环优化:记录最小环大小,记为mc。
Luogu P2921
这部分的代码基本相同,只是在找到环时 更新起点的ic与mc数组。 优化的部分是之前遍历过时,利用唯一性 优化。同样分两类:在环中、不在环中。
不在环中
所以长度自然就是 count+ic[rec[pt]]-dfn[pt]+mc[pt];
DFS 一条路走到黑 碰到以前走过的路再返回。 所以只需要一个vis数组记录 走过的路 方便快捷
BFS 能走就走 碰到以前走过的路就不走。 所以需要记录每次走的点 浪费空间和码力,垃圾 代码略
欧拉路
欧拉路:不重不漏地走完每条边的路径称 为欧拉路,此类问题也叫一笔画问题。 图论的起源就是人们研究一个一笔画问题: 七桥问题,所以第一个学习它。
观察代码,还可以进一步化简:
Luogu P2921
时间复杂度O(很快) 有些题目,尤其是图论和动规题都可以分 类讨论做或者优化。本题分类如图:
Luogu P2921
解法来源于网络,原文可能更容易理解 (据说用Tarjan很……算了我不会Tarjan) https:///blog/planetarian/solutio n-p2921 By cjrsacred
在环中
这怎么算? 事情好像没这么简单。因为路径唯一,之 前走过了这个点,也绝对会走到入环的 点…… 这种情况是不可能存在的。
在环中
所以如果当前点在环中且被走过,必然就 是入环点了。入环时间ic[pt]自然就是count。 答案则是ic[pt]+mc[rec[pt]]
Luogu P2921
那么怎么分类呢?很简单,直接判断 ic[rec[pt]]-dfn[pt]即可。
欧拉路
定义奇点为与这个点相连的边数 为奇数 的点。 欧拉路的特点是奇点个数为2或0。 偶数点进去一次,就要出去一次。 按照这个思路,奇数点只能是起点或终点。 那么0个奇点的图就可以反复进出,也就 是形成环。这样的特殊欧拉路称为欧拉回路。
欧拉路
综上所述,求欧拉路要先求奇点,判断存 在性。之后就使用DFS求解。 并且要注意欧拉回路的情况,既然是环, 从任意点开始遍历皆可。 时间复杂度O(m+n)
欧拉路
以上的程序只是基本框架,输入数据不带 边权,保证有解。 在实际实现时,还会考虑连通性(如果不 联通就绝对无解)和边权(题目可能会要求 存在多条路径时 根据边权戳记录每个节点第一次被访问的顺序, 记为dfn[x]。时间戳有许多应用,比如找最小 环。
Luogu P2661 信息传递