tarjan强连通分量算法个人理解
来源:互联网 发布:淘宝的等级怎么升级快 编辑:程序博客网 时间:2024/05/17 04:10
图中的强连通分量是指图中的一块区域,其中任意两点都能找到到对方的路,而且这块区域不能再加入别的点。
一个环就是一个的强连通分量。
长得复杂一点的强连通分量不过是有公共节点的多个环而已。 //有公共边肯定有公共节点
所以求强连通分量实际上是个找环问题。
找单个环的话,用dfs转一圈回到自己就能找到一个环,但是我们要找的是套在一起的所有环,那就把dfs改一下。
既然dfs转回自己是成环的条件,那么我们称该点为环的根节点,这一点满足在dfs遍历过程中它能转回的最早出现的点是自己(不然更早出现的点能转回这个所谓的“根节点”,就有更大的环了)。
我们按照dfs遍历的顺序把节点压入栈,然后在根节点完成dfs时出栈,直到根节点出栈,即得到强连通分量。
如图我们转圈圈的顺序是
1->3->5->6
6出栈
5出栈
4->1 发现4能转回1,更新4,3,1能转回的最早时间
1->2->4 发现2能转回4,更新2能转回的最早时间
1的dfs完成,发现自己能转回的最早点是自己
2出栈
4出栈
3出栈
1出栈
完成!!
int dfn[1000]={0}; //节点在dfs过程中出现的时间int low[1000]; //一个节点能转回的最早出现的节点出现的时间int stk[1000]; //节点栈int vis[1000]; //节点是否在栈中int stktop=0; //栈顶位置int ind=0; //当前时间int n,m; //点数,边数void tarjan(int pos){ dfn[pos]=low[pos]=++ind;//更新时间 stk[stktop++]=pos;//入栈 vis[pos]=1;//我在栈里!! for(int i=0;i<n;i++) if(graph[pos][i]!=inf) if(dfn[i]==0)//如果这个点没来过 { tarjan(i);//和dfs一样,就接着往深处去 low[pos]=low[pos]<low[i]?low[pos]:low[i];//如果我的后代能转回我的祖先,我肯定能! } else if(vis[i]) low[pos]=low[pos]<dfn[i]?low[pos]:dfn[i];//让我能转回的节点保持最早 if(dfn[pos]==low[pos])//能转回的最早出现的点是自己,已确认是根节点,开始出栈 { vis[pos]=0; while(stk[--stktop]!=pos) { //强连通分量求出来了,干点什么吧 //dosth(stk[stktop]); } }}
阅读全文
0 0
- tarjan强连通分量算法个人理解
- 强连通算法--Tarjan个人理解+详解
- 强连通分量 Tarjan算法
- 强连通分量 tarjan算法
- 强连通分量Tarjan算法
- Tarjan强连通分量算法
- 强连通分量Tarjan算法
- 强连通分量Tarjan算法
- 强连通分量 Tarjan算法
- 强连通分量-tarjan算法
- 【理解】 有向图强连通分量 Tarjan算法
- 对于Tarjan强连通分量算法的理解
- 强连通分量之tarjan算法
- Tarjan算法求强连通分量
- POJ 2186 强连通分量 Tarjan算法
- 强连通分量算法Kosaraju 和 Tarjan
- 求强连通分量的Tarjan算法
- 强连通分量-tarjan算法模板详解
- geopandas简单绘图及横坐标调整
- Eclipse中导入外部jar包
- 编程经验积累
- Think in java第二、三章 总结随笔
- Win10 S尽然如此对待Linux分支
- tarjan强连通分量算法个人理解
- Unity推送SDk
- 数学1(n^n)Leftmost Digit
- find命令进阶用法(一)
- 易语言操作sql server完整教程
- android gradle统一版本
- TCL笔记
- butterknife架构核心
- L1-011. A-B