有向图Kosaraju算法的正确性证明
来源:互联网 发布:英魂之刃开挂软件 编辑:程序博客网 时间:2024/05/04 15:36
Kosaraju的工作过程是:
1.在给定的一副有向图G中,首先取得它的反向图,然后计算反向图的逆后续排列
2.在G中进行标准的深度优先搜索,但是搜索的顺序是按照第一步中计算得出的顺序而非标准顺序来访问所有未被标记的顶点
3.在构造函数中,所有在同一个递归dfs()调用中被访问到的顶点都在同一个强连通分量中,可以通过标记来把它们取出来。
命题:
使用深度优先搜索查找给定有向图G的反向图G1,根据G1计算出所有顶点的逆后续排列,然后根据该逆后续排列去深度优先处理有向图G,其构造函数中的每一次递归调用所标记的顶点都在同一个联通分量中。
证明过程:
1.首先要用反证法证明”每个和s强联通的顶点v都会在dfs(G,s)的过程中被访问到”。那么现在假设有一个和s强联通的v顶点在dfs(G,s)的过程中没有被访问到,因为存在s到v的路径那么说明在此之前该v顶点已经被标记过了,但又因为是强联通所以也存在v到s的路径,所以之前访问到v的时候s也一定被标记过了,所以dfs(G,s)不会被执行。这和之前相互矛盾,所以该命题得证。
2.在进行第二步的证明之前我们先看一看一幅图所有顶点的逆后序顺序的性质,逆后序是在对图进行深度优先搜索的时候把顶点存入一个栈中,部分代码如下:
void dfs(Digraph G,int v){ marked[v]=true; for(int w:G.adj(v)) if(!marked[w]) dfs(G,w); reversePost.push(v);}
不难得出,逆后序的这种行为会导致在reversePost这个栈中,任意一个子节点存放皆后于父节点,也就是说所有只有当所有子节点都入栈了,父节点才入栈(这也正是拓扑排序要用到逆后序的原因)。
清楚这一点后我们开始第二步的证明:
证明”构造函数调用的dfs(G,s)所到达的任意顶点v都必然是和s强联通的”
设v为dfs(G,s)调用中到达的某个顶点,那么G中必然存在一条从s到v的路径,因此现在只需证明G中有一条v到s的路径即可,这等价于证明反向图G1中存在一条从s到v的路径。证明的核心在于,按照逆后续进行的深度优先搜索意味着,在G1中进行的深度优先搜索中,dfs(G,v)必然在dfs(G,s)结束之前就结束了,这样dfs(G,v)的调用就只有两种情况:
①:调用在dfs(G,s)之前(并且也在dfs(G,s)结束之前结束)
②:调用在dfs(G,s)之后(并且也在dfs(G,s)结束之前结束)
第一种情况是不可能出现的,第一步已经证明了。而第二种情况则说明在G1中存在一条从s到v的路径。证明完毕。
ps:【本蒟蒻希望尽快把算法4刷完…】
- 有向图Kosaraju算法的正确性证明
- Kosaraju算法的证明
- Kosaraju算法查找有向图的强连通分支
- Kosaraju算法 有向图的强连通分量
- 有向图的强连通分解--Kosaraju算法
- kosaraju算法-求解有向图SCC
- krusal算法正确性的证明
- 《算法4》有向图与DAG与Kosaraju算法
- 有向图强连通分量的Tarjan算法和Kosaraju算法
- 【有向图的强连通分】HDUOJ 1269 迷宫城堡(Kosaraju算法+Tarjan算法)
- 有向图强连通分量Kosaraju算法
- hdu1269 有向图 强连通分量 kosaraju 算法
- hdu2767 Proving Equivalences,有向图强联通,Kosaraju算法
- 有向图—拓扑排序,Kosaraju算法
- 有向图(6)--计算强连通分量的Kosaraju算法
- Kosaraju 算法求解一个有向图的强连通分支个数
- 有向图的强连通分支算法kosaraju(C语言实现)
- Kosaraju算法的分析和证明
- 多项目管理五大特点
- tcpdump 命令
- 什么是雾计算?它与云计算有什么区别?
- Docker命令解读-六
- 折半查找
- 有向图Kosaraju算法的正确性证明
- ROM存储器分类
- Spring IOC原理
- 几个html标签
- 各种跟CV、AR相关的C/C++代码收集
- 推荐系统简单介绍
- 解耦模式--事件队列
- Docker命令解读-七
- 给两年后的自己