强连通分量(模板)
来源:互联网 发布:软件功能过期怎么办 编辑:程序博客网 时间:2024/06/14 23:09
对图深度优先搜索,定义DFS(u)为u在搜索树(以下简称为树)中被遍历到的次序号。定义Low(u)为u或u的子树中能通过非父子边追溯到的最早的节点,即DFS序号最小的节点(这个好像有点问题,原文评论说改为:low(u)为u或u的子树通过最多一条反向边能够追溯到的最早的栈中节点的次序号。好像对?)。根据定义,则有:
Low(u)=Min{DFS(u)DFS(v) (u,v)为后向边(返祖边) 等价于 DFS(v)<DFS(u)且v不为u的父亲节点Low(v) (u,v)为树枝边(父子边)}
/*复杂度为O(m+n)*/#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define MOD 100000#define inf 1<<29#define LL long long#define MAXN 20010#define MAXM 50010using namespace std;struct Edge{ int to,next;} edge[MAXM*2];int head[MAXM*2],tot;int low[MAXN],DFN[MAXN],belong[MAXN];///belong 的值为1-sccint index,top;int scc ; ///强连通分量bool inStack[MAXN];int num[MAXN],stack[MAXN]; ///num为各个强连通分量包含的点的个数,数组编号1-scc num数组不一定需要,结合实际情况void addedge(int u,int v){ edge[tot].to = v;low edge[tot].next = head[u]; head[u] = tot++ ;}void Tarjan(int u) ///遍历当前点u的邻接所有点v{ int v; low[u] = DFN[u] = ++index; stack[top++] = u; inStack[u] = true; for(int i=head[u] ; i!=-1 ; i=edge[i].next) { v = edge[i].to; if( !DFN[v] ) ///当前点v没有被标号 { Tarjan(v); if(low[u]>low[v]) low[u] = low[v]; } else if( inStack[v] && low[u] > DFN[v]) ///当前点v之前被标记过 <a target=_blank href="http://blog.csdn.net/u014665013/article/details/51351371">后向边</a> low[u] = DFN[v]; ///这里可以是low[u] = DFN[v] 不是Low[v] } if(low[u] == DFN[u]) ///找到一个强连通分量 { scc++; do { v=stack[--top]; ///清空当前强连通分量栈 必须清空 inStack[v] = false; belong[v]=scc; num[scc]++; } while(v!=u); }}void solve(int N){ for(int i=1; i<=N ; i++) if( !DFN[i] ) Tarjan(i);}void init() ///如果数组太大没必要全部初始化{ tot = index = scc = top =0; memset(DFN,0,sizeof(DFN)); memset(inStack,false,sizeof(inStack)); memset(num,0,sizeof(num)); memset(head,-1,sizeof(head));}int main (){ int n,m,Case=1; while(~scanf("%d%d",&n,&m)) { int u,v; init(); for(int i=0; i<m; i++) { scanf("%d%d",&u,&v); addedge(u,v); // addedge(v,u); } solve(n); printf("强连通分量为:%d\n",scc); } return 0;}
0 0
- 强连通分量(模板)
- 强连通分量模板
- 强连通分量模板
- 强连通分量模板
- 强连通分量 模板
- 强连通分量模板
- 强连通分量模板
- 强连通分量模板
- 【强连通分量模板】
- 【模板】强连通分量
- 强连通分量模板
- tarjan算法模板(强连通分量)
- 强连通分量Tarjan模板
- Tarjan强连通分量模板
- poj 2186 tarjan求强连通分量(模板题)
- 【强连通分量】nyoj120 校园网络(模板题)
- 浅谈双连通分量、强连通分量(模板)
- POJ 2186 Popular Cows(强连通分量模板题)
- uboot Makefile 分析
- (十二)洞悉linux下的Netfilter&iptables:iptables命令行工具源码解析【下】
- 指令 机器指令 汇编指令 指令系统 汇编指令的基本构成 操作数
- iOS之系列设备的分辨率
- Git 分支 - 分支的新建与合并
- 强连通分量(模板)
- Android SwipeRefreshLayout:谷歌官方SDK包中的下拉刷新
- shadre - SubShader
- 【IMPDP】实现不同用户之间的数据迁移——REMAP_SCHEMA参数
- 用宏简化枚举类型的字符串输出
- (十三)洞悉linux下的Netfilter&iptables:为防火墙增添功能模块【实战】
- Struts之参数传递
- 1081. Rational Sum (20)
- oracle 11g 数据泵导入导出方法