博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Kosaraju算法详解
阅读量:6514 次
发布时间:2019-06-24

本文共 1390 字,大约阅读时间需要 4 分钟。

 
Kosaraju算法可以求出有向图中的强连通分量个数,并且对分属于不同强连通分量的点进行标记。它的算法描述
较为简单:
(1)
第一次对图
G
进行
DFS
遍历,并在遍历过程中,记录每一个点的退出顺序。以下图为例:
 
    如果以
1
为起点遍历,访问结点的顺序如下:
 

 

结点第二次被访问即为退出之时,那么我们可以得到结点的退出顺序:
 
(2)倒转每一条边的方向,构造出一个反图
G
。然后按照退出顺序的逆序对反图进行第二次
DFS
遍历。我们按
1
4
2
3
5
的逆序第二次
DFS
遍历:
 

 

访问过程如下:
 
每次遍历得到的那些点即属于同一个强连通分量。
1
4
属于同一个强连通分量,
2
3
5
属于另一个强连通分量。

 代码:

1 #include
2 #include
3 #include
4 using namespace std; 5 int map[101][101]; 6 int nmap[101][101]; 7 int pass[101]; 8 int vis[101]; 9 int now=1;10 int n,m;11 int num=0;12 void dfs(int p)13 {14 vis[p]=1;15 for(int i=1;i<=n;i++)16 {17 if(vis[i]==0&&map[p][i]==1)18 {19 dfs(i);20 21 }22 }23 pass[now]=p;24 now++;25 }26 void ndfs(int p)27 {28 vis[p]=0;29 for(int i=1;i<=n;i++)30 {31 if(vis[i]==1&&nmap[p][i]==1)32 ndfs(i);33 }34 }35 int main()36 {37 38 scanf("%d%d",&n,&m);39 for(int i=1;i<=m;i++)40 {41 int x,y;42 scanf("%d%d",&x,&y);43 map[x][y]=1;44 nmap[y][x]=1;45 }46 for(int i=1;i<=n;i++)47 {48 if(vis[i]==0)49 dfs(i);50 }51 pass[now]=1;52 for(int i=n;i>=1;i--)53 {54 if(vis[pass[i]]==1)55 {56 ndfs(pass[i]);57 num++;58 }59 }60 cout<

 

转载地址:http://puofo.baihongyu.com/

你可能感兴趣的文章
程序猿知道英语词汇
查看>>
数据存储(两)--SAX发动机XML记忆(附Demo)
查看>>
谈谈SQL 语句的优化技术
查看>>
ecshop如何判断缓存文件是否能更新
查看>>
javascript于boolean类型转换,运营商&amp;&amp;和|| 返回值
查看>>
深入分析面向对象中的封装作用
查看>>
深刻理解Python中的元类(metaclass)
查看>>
Java编程的逻辑 (44) - 剖析TreeSet
查看>>
address元素
查看>>
Android View体系(六)从源码解析Activity的构成
查看>>
fnmatch源码阅读
查看>>
U9249 【模板】BSGS
查看>>
单片机小白学步系列(九) 用万用焊板搭建实验电路
查看>>
(转)全文检索技术学习(三)——Lucene支持中文分词
查看>>
Node.js+Koa开发微信公众号个人笔记(一)准备工作
查看>>
Android 图片缓存处理
查看>>
阿里盒马领域驱动设计实践
查看>>
vuex 存值 及 取值 的操作
查看>>
HDU 2242 考研路茫茫——空调教室(边双连通)
查看>>
如何在C#项目中使用NHibernate
查看>>