强联通分量之kosaraju算法

  首先定义:强联通分量是有向图G=(V, E)的最大结点集合,满足该集合中的任意一对结点v和u,路径vu和uv同时存在。

  kosaraju算法用来寻找强联通分量。对于图G,它首先随便找个结点dfs,求出每个节点最后一次访问的时间戳f(x),然后我们建立反图Gt,接着根据倒序的时间戳来dfs每个节点,每次dfs到的结点集合就是一个强联通分量。事实上这个算法的思想和拓扑排序类似。

  我们来证明它(注意这里面的图指原图,而不是反图):

引理:对于G中的两个强联通分量C和C’,若点u属于C,点v属于C‘,且存在边(u,v),那么f(C)>f(C‘)。

  证明应该很好想。。如果先访问C,那么一定会先访问完C‘再访问C。如果先访问C’,因为强联通分量的性质,C一定不在C’的深度优先搜索树中。

推论:对于G中的两个强联通分量C和C’,若点u属于C,点v属于C‘,如果f(C)>f(C‘),那么不可能存在边(v,u)

  因为若有边(v,u),访问C‘一定会访问到C,然后C先退出。如果先访问C,那么f(C)依旧小于f(C’)

证明:若根据倒序的时间戳dfs结点,那么最后一个结点一定属于最后一个结束访问的强联通分量C‘(因为C’被访问到的次序就是由最后一个结点的时间戳决定的),也就是f(C‘)>f(任意一个C)。根据推论,在原图中不可能存在边,从其它强联通分量连向它。也就是对于反图来说,从当前结点dfs只会dfs到最后一个结束访问的强连通分量。接着,倒序找到第二个没有被访问过的点,它属于倒数第二个结束访问的强联通分量,并且按原图来看,只可能有前面访问过的强联通分量向它连边,所以它只能访问自己所属的强联通分量。以此类推,可以证明算法的正确性。

  这个证明的重点在于:目前倒序来看,最先没有访问过的点属于新的待处理强联通分量。

时间: 2024-11-12 06:18:27

强联通分量之kosaraju算法的相关文章

HDU 1269 迷宫城堡 (强联通分量,Tarjan算法)

Problem Description: 为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A房间和B房间,只说明可以通过这个通道由A房间到达B房间,但并不说明通过它可以由B房间到达A房间.Gardon需要请你写个程序确认一下是否任意两个房间都是相互连通的,即:对于任意的i和j,至少存在一条路径可以从房间i到房间j,也存在一条路径可以从房间j到房间i. Input: 输入包含多组数据

POJ 2186 Popular cows(Kosaraju+强联通分量模板)

题目链接:http://poj.org/problem?id=2186 题目大意:给定N头牛和M个有序对(A,B),(A,B)表示A牛认为B牛是红人,该关系具有传递性,如果牛A认为牛B是红人,牛B认为牛C是红人,那么牛A也认为牛C是红人.求被其他所有牛认为是红牛的牛的总数. 解题思路:把所有牛看成顶点,把有序对(A,B)看成从A到B的有向边,那么题目就变成了求所有顶点都可到达的顶点的总数.我们可以得到一个结论,如果一个强连通分量里有一头牛被认为是红人,那么该强联通分量里的所有牛都是红人,这显然是

【POJ1236】Network of Schools 强联通分量缩点(本文kosaraju)

/*不要说这题多水之类的--我只是想记一下kosaraju这种屌炸天的dfs序延伸算法(说不定能加到我的ygylca里面)*/ 题意神马的都不说了,好吧,就是给你个图,n个点,然后n行每行都描述该点的出边,图建完了,然后缩点,然后问多少个点没有入度,再问需要加几条边可以让图变强联通图. 强联通图:图中任意两点之间都能互相到达(前提得是有向图你懂的,无向图就有点乱了,根本不要算法了,暴搜就好了) 强联通分量:同强联通图,不过是图中一部分. 缩点,把一个分量视为一个点,缩起来(一般不缩,都是记录每个

51nod 1076 2条不相交的路径 无向图强联通分量 trajan算法

1076 2条不相交的路径 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 给出一个无向图G的顶点V和边E.进行Q次查询,查询从G的某个顶点V[s]到另一个顶点V[t],是否存在2条不相交的路径.(两条路径不经过相同的边) (注,无向图中不存在重边,也就是说确定起点和终点,他们之间最多只有1条路) Input 第1行:2个数M N,中间用空格分开,M是顶点的数量,N是边的数量.(2 <= M <= 25000, 1 <= N <=

POJ 2186-Popular Cows (图论-强联通分量Korasaju算法)

题目链接:http://poj.org/problem?id=2186 题目大意:有n头牛和m对关系, 每一对关系有两个数(a, b)代表a牛认为b牛是“受欢迎”的,且这种关系具有传递性, 如果a牛认为b牛“受欢迎”, b牛认为c牛“受欢迎”, 那么a牛也认为c牛“受欢迎”. 现在想知道有多少头牛受除他本身外其他所有牛的欢迎? 解题思路:如果有两头或者多头牛受除他本身外其他所有牛的欢迎, 那么在这两头或者多头牛之中, 任意一头牛也受两头或者多头牛中别的牛的欢迎, 即这两头或者多头牛同属于一个强联

tarjan算法求强联通分量

昨天学到了一个新的算法tarjan算法,感觉最近都没有怎么学习了...(最近有个感悟啊,就是学习一定的通过实践来进步的. 现在才明白为什么高中的时候老师强调一定要刷题,当然刷完题目之后的总结也非常地重要! 这个tarjan算法用来求强联通分量,在网上看了几篇blog,然后做了一个题目,感觉这个算法很nice啊... 如果没有学这个算法, 我肯定会想直接dfs吧orz... dfs看看是不是每个点能到达连通分量的其他点,好像这样非常麻烦啊,还要记录这个点从哪里来的...这样一想,好像直接dfs我做

[图论] 有向图强连通分量 (kosaraju算法,Tarjan算法)

记录自己的想法:在有向图中,如果一些顶点中任意两个顶点都能互相到达(间接或直接),那么这些顶点就构成了一个强连通分量,如果一个顶点没有出度,即它不能到达其他任何顶点,那么该顶点自己就是一个强连通分量.在用kosaraju算法和Tarjan算法求强连通分量的时候,就是给所有的顶点分组染色,同一种颜色的顶点在同一个强连通分量中,记录有多少种颜色(有多少个强联通分量),每个顶点属于哪种颜色(每个顶点在哪个强连通分量重).在同一个强连通分量中的所有顶点可以缩为一个顶点,然后根据缩点构造DAG(有向无环图

Tarjan的强联通分量

求强联通分量有很多种. <C++信息学奥赛一本通>  中讲过一个dfs求强联通分量的算法Kosdaraju,为了骗字数我就待会简单的说说.然而我们这篇文章的主体是Tarjan,所以我肯定说完之后再赞扬一下Tarjan大法好是不是 首先我们讲一下强联通分量 强联通分量指的是图的一个子图.在这个子图中,任意两个节点都可以互相到达.从定义上我们就可以看出是一个有向图来,因为任意一个无向图都符合该定义. 而它的标准定义是:有向图中任意两点都联通的最大子图. 咳咳,首先庆祝一下哈--本人博客的第一张图.

有向图的强联通分量

最近学了有向图的强联通分量.有kosaraju算法,不过写着比tarjin麻烦.所以就只记录tarjin算法. 跟求无向图的双连通分量很相似,先贴代码. 1 void dfs(int u){ 2 dfn[u]=low[u]=++clk;//dfn序 3 stk[top++]=u;//压入栈内 4 for(int i=head[u];i;i=edge[i].nxt){ 5 int t=edge[i].to; 6 if(dfn[t]==0){//如果下一个节点是没有访问过的 7 dfs(t); 8