有向图强连通分量Tarjan模板
2016-04-06 17:30
381 查看
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int maxn=10010; const int maxm=1000010; int cnt,p[maxn]; struct node { int v,next; }E[maxm]; int n,m; int low[maxn],dfn[maxn]; int Stack[maxn];///数组模拟栈 int num[maxn];///记录第i个连通块点的个数 int Scc[maxn];///第i个点属于哪个连通块 int scc;///连通块计数 int Time;///dfs的时间戳 bool instack[maxn];///点是否在栈里 int top;///栈里点的个数 void init() { cnt=0; memset(p,-1,sizeof(p)); } void add(int u,int v) { E[cnt].v=v; E[cnt].next=p[u]; p[u]=cnt++; } void Tarjan(int u) { dfn[u]=low[u]=++Time; Stack[++top]=u; instack[u]=1; int v; for(int i=p[u];i!=-1;i=E[i].next) { v=E[i].v; if(!dfn[v])///由于dfn初始化为0,所以可以判断是否访问 { Tarjan(v); if(low[u]>low[v]) low[u]=low[v]; } else if(instack[v]&&low[u]>dfn[v]) low[u]=dfn[v]; } if(low[u]==dfn[u]) { scc++; while(1) { v=Stack[top--]; instack[v]=0; num[scc]++; Scc[v]=scc; if(u==v) break; } } } void solve() { for(int i=1;i<=n+1;i++) { dfn[i]=num[i]=Scc[i]=0; instack[i]=0; } Time=scc=top=0; for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i); } int main() { while(scanf("%d%d",&n,&m),n||m) { init(); for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); add(x,y); } solve(); if(scc==1) puts("Yes"); else puts("No"); } return 0; }
相关文章推荐
- 1231 - Coin Change (I) 多重背包
- android MVVM框架的搭建
- JSP开发模式及MVC
- poj 3254(状态压缩dp)
- django 分页(2) 使用类 页码显示
- SpringMVC入门
- 改变对update的做法
- matlab暗通道图像去雾算法实现
- 在百度地图API开发中已知两个点之间的经纬度坐标计算其距离
- C++ Mfc 吹泡泡程序编程实例 下载
- linux 进程调度
- 快速排序
- 冒泡排序 - Bubble Sort
- SQL Server日期函数总结
- IOS开发-UI学习-UIPageControl(页码控制器)的使用
- Linux VSFTP服务器详细配置
- mysql主从复制及自动备份脚本
- xcode打包出错:User interaction is not allowed
- 几种常见排序算法的JavaScript实现
- python核心编程中的对象值比较VS对象身份比较