强连通分量 洛谷2818
2017-02-18 09:37
141 查看
本次专题是强连通分量的tarjan算法,以下程序包含stl建图,dfs遍历,强连通分量假缩点,求缩点入度出度。
#include<iostream> #include<cstdio> #include<stack> #include<vector> #include<cmath> #define M 10005 using namespace std; stack<int>S; int pre[M],//dfs的步数(时间) low[M],//若属于同一强连通分量,则Low值更改为之前的最小时间; c[M],k[M], belong[M],//记录是否属于同一强连通分量 in[M],//分量入度 out[M];//分量出度 int m,n,time1,time2,t1,t2,w; vector<int>g[M]; void dfs(int u) { pre[u]=low[u]=time1++;//步数+1 S.push(u);//当前节点出栈 for(int i=0;i<g[u].size();i++)//遍历当前节点所连结点 { int v=g[u][i]; if(!pre[v])//若未被遍历 { dfs(v); low[u]=min(low[u],low[v]);//low值更改 } if(!c[v]) low[u]=min(pre[v],low[u]); } if(pre[u]==low[u])//若当前节点步数值等于low值,则一个强连通分量构成 { time2++;//分量数+1 while(1) { int x=S.top();S.pop();//出栈 c[x]=time2; belong[x]=time2; if(x==u)break; } } } void find() { for(int i=1;i<=n;i++) if(!pre[i])dfs(i); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { while(1) { scanf("%d",&t1); if(t1==0)break; g[i].push_back(t1); } } find(); for(int i=1;i<=n;i++) for(int j=0;j<g[i].size();j++) { int v=g[i][j]; if(belong[i]!=belong[v])//若不属于同一强连通分量 { in[belong[v]]++;//下一分量入度加1 out[belong[i]]++;//当前分量出度加1 } } //以下过程针对 洛谷P2812 /*int ans1=0,ans2=0; for(int i=1;i<=time2;i++) { if(in[i]==0) ans1++; if(out[i]==0) ans2++; } if(time2==1) { printf("1\n0"); return 0; } ans2=max(ans1,ans2); printf("%d\n%d",ans1,ans2);*/ return 0; }
相关文章推荐
- 强连通分量与缩点(Tarjan算法)(洛谷P3387)
- 强连通分量模板+DAGdp 洛谷P3387
- 重连通分量的求解
- POJ 2236 Wireless Network 【并查集的简单应用 判断是否在同一连通分量】
- hdu 1198 dfs||并查集求连通分量个数,关键建图
- Tarjan求强连通分量
- 强连通分量模板
- 有向图强连通分量的Tarjan算法
- 4612 warm up tarjan+bfs求树的直径(重边的强连通通分量)忘了写了,今天总结想起来了。
- 强连通分量
- [poj 1904]King's Quest[Tarjan强连通分量]
- 有向图tarjan算法求连通分量的粗浅讲解、证明, // hdu1269
- BZOJ 1064 假面舞会(图论-连通分量)
- ZOJ_1462 Team Them Up! 求完连通分量后,再进行背包,之后背包路径回溯
- poj1144--D - Network(连通分量,割点)
- 求有向图的强连通分量 Tarjan算法学习笔记
- 强连通分量(桥)
- 图论算法(6) --- Tarjan算法求强连通分量
- 【图论】连通分量个数(并查集)
- ssl1759-求连通分量【图论,深搜,广搜】