点连通分量+边连通分量+割点和桥+强连通分量
2014-08-10 17:42
337 查看
老是搞不清他们的关系,不知道该用那份代码,今天理了一下,整理一下模板
点连通分量:可以求出点连通分量包含哪些点,那个点属于那个连通分量
边连通分量:点连通分量是找到一个割点后,把栈里的点划分到联通分量里,而边连通分量是所有孩子处理完了,才划分
割点和桥:
有向图强连通分量:
点连通分量:可以求出点连通分量包含哪些点,那个点属于那个连通分量
struct edge { int u,v; }; int pre[maxn],iscut[maxn],bccno[maxn],dfs_clock,bcc_cnt; vector<int> G[maxn],bcc[maxn]; stack<edge> s; int n; int dfs(int u,int fa) { int lowu=pre[u]=++dfs_clock; int child=0; for(int i=0;i<G[u].size();i++) { int v=G[u][i]; edge e=edge{u,v}; if(!pre[v]) { s.push(e); child++; int lowv=dfs(v,u); lowu=min(lowu,lowv); if(lowv>=pre[u]) { iscut[u]=true; bcc_cnt++;bcc[bcc_cnt].clear(); while(true) { edge x=s.top();s.pop(); if(bccno[x.u]!=bcc_cnt){bcc[bcc_cnt].push_back(x.u);bccno[x.u]=bcc_cnt;} if(bccno[x.v]!=bcc_cnt){bcc[bcc_cnt].push_back(x.v);bccno[x.v]=bcc_cnt;} if(x.u==u&&x.v==v)break; } } } else if(pre[v]<pre[u]&&v!=fa) { s.push(e); lowu=min(lowu,pre[v]); } } if(fa<0&&child==1)iscut[u]=0; return lowu; } void find_bcc(int m) { memset(pre,0,sizeof(pre)); memset(iscut,0,sizeof(iscut)); memset(bccno,0,sizeof(bccno)); dfs_clock=bcc_cnt=0; for(int i=0;i<=m;i++) if(!pre[i])dfs(i,-1); }
边连通分量:点连通分量是找到一个割点后,把栈里的点划分到联通分量里,而边连通分量是所有孩子处理完了,才划分
struct edge { int u,v; }; int pre[maxn],low[maxn],iscut[maxn],bccno[maxn],dfs_clock,bcc_cnt; int deg[maxn]; vector<int> grid[maxn],bcc[maxn]; stack<int> s; void dfs(int u,int fa) { pre[u]=low[u]=++dfs_clock; s.push(u); int biao=0; for(int j=0; j<grid[u].size(); j++) { int v=grid[u][j]; if(!pre[v]) { dfs(v,u); low[u]=min(low[v],low[u]); } else if(pre[v]<pre[u]&&v!=fa) low[u]=min(low[u],pre[v]); } if(pre[u]==low[u]) { int j; bcc_cnt++; do { j=s.top();s.pop(); bccno[j]=bcc_cnt; } while(j!=u); } }
割点和桥:
void dfs(int u,int fa) { low[u]=pre[u]=++dfs_clock; int child=0; for(int i=0;i<g[u].size();i++) { int v=g[u][i]; if(!pre[v]) { child++; dfs(v,u); low[u]=min(low[v],low[u]); if(low[v]>=pre[u]) iscut[u]=true; } else if(pre[v]<pre[u]&&v!=fa) low[u]=min(low[u],pre[v]); } if(fa<0&&child==1)iscut[u]=false; }
有向图强连通分量:
vector<int> grid[maxn]; int lowlink[maxn],pre[maxn],sccno[maxn],dfs_clock,scc_cnt; stack<int> s; void dfs(int u) { pre[u]=lowlink[u]=++dfs_clock; s.push(u); for(int i=0;i<grid[u].size();i++) { int v=grid[u][i]; if(!pre[v]) { dfs(v); lowlink[u]=min(lowlink[u],lowlink[v]); } else if(!sccno[v]) { lowlink[u]=min(lowlink[u],pre[v]); } } if(lowlink[u]==pre[u]) { scc_cnt++; while(true) { int x=s.top();s.pop(); sccno[x]=scc_cnt; if(x==u)break; } } } bool find_scc() { dfs_clock=scc_cnt=0; memset(sccno,0,sizeof(sccno)); memset(pre,0,sizeof(pre)); while(!s.empty())s.pop(); dfs(1); for(int i=1;i<=n;i++) if(!pre[i])dfs(i); if(scc_cnt>1)return false; return true; }
相关文章推荐
- 连通分量模板:tarjan: 求割点 && 桥 && 缩点 && 强连通分量 && 双连通分量 && LCA(近期公共祖先)
- 连通分量模板:tarjan: 求割点 && 桥 && 缩点 && 强连通分量 && 双连通分量 && LCA(最近公共祖先)
- tarjan算法(割点/割边/点连通分量/边连通分量/强连通分量)
- 强连通图_割点_割边(桥)_双向连通分量关系
- [笔记]: Tarjan算法求有向图的强连通分量
- hdu 4587 推断孤立点+割点+ 删除点之后,剩下多少连通分量
- 一句话之--tarjan算法、kosaraju算法,求强连通分量
- 【强连通分量缩点】poj 1236 Network of Schools
- 强连通分量-tarjan算法
- tarjan求强连通分量
- 有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,
- 9.5-uva-1627-Team them up-动态规划-图-连通分量-DFS(WA)
- EOJ 3464/NEERC 2017 C.Connections【Kosaraju求强连通分量】
- POJ 1523 SPF 求割点及对应的连通分量数
- 重连通分量 (Biconnected Component)
- 强连通分量 (转)
- <zz>有向图强连通分量的Tarjan算法
- 强连通分量-Trajan算法
- 转一篇求图割点、连通分量的文章
- 有向图的强连通分量 SCC tarjin算法