tarjan 强连通 模板
2016-07-27 15:20
253 查看
2SAT中的重要知识 以前学过忘记存了。现在存一发免得再忘了
#include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> #include <iostream> #include <vector> #include <cmath> #include <map> #include <string> #include <stack> #include <queue> using namespace std; const int MAXN=1e5+10; struct node { int v; int nxt; }; node edge[MAXN];//边数 int head[MAXN]; int n,m; int Stop,Bcnt,Dindex;//栈头,强通块数,时间戳 int DFN[MAXN],LOW[MAXN];//首时间戳,最近回溯点(根) int Stap[MAXN];//答案栈 int instack[MAXN];//是否在栈中 int Belong[MAXN];//这个点属于第几个强连通块(点) int cnt=0; void add_edge(int u,int v) { edge[cnt].v=v; edge[cnt].nxt=head[u]; head[u]=cnt; cnt++; } void tarjan(int i) { int j; DFN[i]=LOW[i]=++Dindex; instack[i]=1; Stap[++Stop]=i; for (int e=head[i]; e!=-1; e=edge[e].nxt) { j=edge[e].v; if (!DFN[j])//儿子没遍历 { tarjan(j);//遍历 if (LOW[j]<LOW[i])//如果儿子已经形成环 LOW[i]=LOW[j];//父亲也要在回溯的时候进入环 } else if (instack[j]&&DFN[j]<LOW[i])//邻接的在栈里,所以是大大 LOW[i]=DFN[j];//把这个点归到大大那 } if (DFN[i]==LOW[i])//这个点的根是自己 { Bcnt++;//多了一个强连通分量 do { j=Stap[Stop--];//退栈 instack[j]=0;//标记 Belong[j]=Bcnt;//标记 } while (j!=i); } } void solve() { int i; Stop=Bcnt=Dindex=0;//栈头,强通块数,时间戳 memset(DFN,0,sizeof(DFN)); for (int i=1; i<=n; i++) if (!DFN[i]) tarjan(i); } int main() { while (scanf ("%d%d",&n,&m)!=EOF) { memset(head,-1,sizeof(head)); while (m--) { int t1,t2; scanf ("%d%d",&t1,&t2); add_edge(t1,t2); } solve(); } return 0; }
相关文章推荐
- ios数据存储——对象归档
- HDU-4533 威威猫系列故事——晒被子(区间更新)
- html往js文件传递参数
- 类似智联招聘选择职位的弹出框效果,可做选择城市等信息
- win7 iis 未能加载文件或程序集“Oracle.DataAccess, Version=4.112.3.0...
- JDBC数据源连接池的配置和使用实例
- Baidu地图开发,定位,检索
- Java数据库连接池的几种配置方法(以MySQL数据库为例)
- behave-Tutorial01-来个简单示例
- 工作杂记
- servlet 具体实现
- python3 匹配任意字符
- java开发中的23中设计模式
- 问题
- 函数(5)
- 数独
- 去111
- js最近天数
- I.MX6 Ethernet MAC (ENET) MAC Address hacking
- 自定义navigationitem时,button的状态颜色问题