双连通分量(DCC)
来源:互联网 发布:vue.js 页面加载动画 编辑:程序博客网 时间:2024/06/09 16:50
求双连通分量(tarjan方法)
解释都在代码里:
#include<iostream>#include<cstdio>#include<cstring>#define CLR(a,b) memset(a,b,sizeof(a))#define Min(a,b) a>b?b:ausing namespace std;const int INF=1e5+5;int dfn[INF]; //记录各结点的访问次序int low[INF]; //low是追溯到DCC的根节点的dfn的值 //当根节点的某个直接儿子节点的low值大于或等于根节点的dfn的值时, //就可以从栈中取值了,直到取到根节点为止时就是一个DCC int dcc_id[INF]; //存储各节点的所在的编号(就是你给他们编的号,从1到n)cnt_dcc就是编号下标! int stack[INF]; //栈:用深搜搜索节点并依次存储各个节点—以便于找到DCC //即当发现环时就是一个DCC,用low标记的,从该栈中取值取到该根节点为止 int father[INF]; //由于求DCC是在一个无向连通图中,即为双向的图 //该father就是为了防止某一节点又访问上一个节点(上一个节点搜出该节点) int top,cnt_dcc,cnt_idex;struct Edge //存储边的信息{ int to; Edge *next;};Edge *edge[INF];void tarjan(int u){ dfn[u]=low[u]=++cnt_index; stack[++top]=u; for(Edge *temp=edge[u];temp;temp=temp->next) { int v=temp->to; if(!dfn[v]) { father[v]=u; tarjan(v); low[u]=Min(low[u],low[v]); //更新low使每一个DCC中的low的值==根节点low值 if(low[v]>=low[u]) //当发现节点u的儿子节点v的low值>=dfn[u] { //则就要取栈,即是时候取出DCC了 cnt_dcc++; int j; do { j=stack[top--]; dcc_id[j]=cnt_dcc; }while(v!=j); top++; //这里为什么要++?因为连着DCC是有共同节点的 } } else if(v!=father[v]) low[u]=Min(low[u],dfn[v]); }}void solve(int node) //node 为要深搜的结点{ top=cnt_dcc=cnt_idex=0; CLR(dfn,0); tarjan(node); //由于是无向连通图,只需深搜一个节点就都可以都到了 }
- 双连通分量(DCC)
- hdu4738(双连通分量)
- hdu 2242(边双连通分量)
- uva 10972(边双连通分量)
- UVA 10972(边双连通分量)
- poj3352Road Construction(边双连通分量)
- 双连通分量(点+边)
- 双连通分量
- 双连通分量_road
- 边双连通分量
- 双连通分量
- 双连通分量-tarjan
- 双连通分量
- 双连通分量
- 双连通分量-tarjan
- 双连通分量
- poj3177 双连通分量
- 点双连通分量
- 生活中最毁身体的坏姿势(转载)
- 生成java在命令行下可执行的jar
- java中的多线程
- ubuntu12.04修复grub方法
- Makefile教程
- 双连通分量(DCC)
- centos下设置iptables
- hdu 1010 (DFS+剪枝)
- Rest风格的web服务开发-入门篇1
- 用例图、活动图和顺序图的关系
- 工作流三位一体的驱动方式- (表单)数据 状态 人工
- 黄生借书说
- 如何查找.NET程序内存不断上涨的原因(CLRProfiler)
- proxool详细配置