KS求有向图强连通分量模板

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4
  5 int n,m;
  6 const int maxn=1e5+2;
  7 const int maxm=2*maxn;
  8 struct nodeg
  9 {
 10     int to;
 11     int nxt;
 12 }eg[maxm];
 13 int headg[maxn];
 14 int headgr[maxn];
 15 struct nodegr
 16 {
 17     int to;
 18     int nxt;
 19 }egr[maxn];
 20 int totg;
 21 int totgr;
 22 int id=0;
 23 int num[maxn];
 24 bool vis[maxn];
 25 int root;
 26 int cnt;
 27 void init()
 28 {
 29     memset(headg,-1,sizeof(headg));
 30     memset(headgr,-1,sizeof(headgr));
 31     totg=0;
 32     totgr=0;
 33     cnt=0;
 34 }
 35 void addg(int u,int v)
 36 {
 37     eg[totg].to=v;
 38     eg[totg].nxt=headg[u];
 39     headg[u]=totg++;
 40 }
 41 void addgr(int u,int v)
 42 {
 43     egr[totgr].to=v;
 44     egr[totgr].nxt=headgr[u];
 45     headgr[u]=totgr++;
 46 }
 47 vector<int> scc[maxn];
 48 void DFS(int u)
 49 {
 50     vis[u]=true;
 51     for(int i=headg[u];i!=-1;i=eg[i].nxt)
 52     {
 53         int v=eg[i].to;
 54         if(!vis[v])
 55         {
 56             DFS(v);
 57         }
 58     }
 59     num[++id]=u;
 60 }
 61 void RDFS(int u,int k)
 62 {
 63     vis[u]=true;
 64     scc[k].push_back(u);
 65     for(int i=headgr[u];i!=-1;i=egr[i].nxt)
 66     {
 67         int v=egr[i].to;
 68         if(!vis[v])
 69         {
 70             RDFS(v,k);
 71         }
 72     }
 73 }
 74 void SCC()
 75 {
 76         memset(vis,false,sizeof(vis));
 77         for(int i=1;i<=n;i++)
 78         {
 79             if(!vis[i])
 80             {
 81                 DFS(i);
 82             }
 83         }
 84         memset(vis,false,sizeof(vis));
 85         for(int i=1;i<=n;i++)
 86         {
 87             scc[i].clear();
 88         }
 89         cnt=0;
 90         for(int i=id;i>=1;i--)
 91         {
 92             if(!vis[num[i]]) RDFS(num[i],++cnt);
 93         }
 94 }
 95 void printSC()
 96 {
 97     for(int i=1;i<=cnt;i++)
 98     {
 99         int sz=scc[i].size();
100         for(int j=0;j<sz;j++)
101             printf("%d ",scc[i][j]);
102         puts("");
103     }
104 }
105
106 int main()
107 {
108     while(~scanf("%d%d",&n,&m))
109     {
110         init();
111         int u,v;
112         for(int i=1;i<=m;i++)
113         {
114             scanf("%d%d",&u,&v);
115             addg(u,v);
116             addgr(v,u);
117         }
118         SCC();
119         printSC();
120     }
121
122     return 0;
123 } 

Kosaraju-Sharir算法

http://www.cnblogs.com/llhthinker/p/4954082.html

时间: 2024-10-12 23:29:39

KS求有向图强连通分量模板的相关文章

Tarjan算法求有向图强连通分量并缩点

// Tarjan算法求有向图强连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<queue> using namespace std; const int N = 100010, M = 1000010; // int ver[M], Next[M], head[N],

tarjan模板(缩点,求有向图强连通分量)

具体思路见详解网址:https://www.byvoid.com/blog/scc-tarjan: 然后整理出了这个tarjan模板,具体数组的功能代码都有注释. const int N=100010; struct data { int to,next; } tu[N*2]; int head[N]; int ip; int dfn[N], low[N];///dfn[]表示深搜的步数,low[u]表示u或u的子树能够追溯到的最早的栈中节点的次序号 int sccno[N];///缩点数组,表

对求有向图强连通分量的tarjan算法原理的一点理解

先简单叙述一下tarjan算法的执行过程(其他诸如伪代码之类的相关细节可以自己网上搜索,这里就不重复贴出了): 用到两类数组: dfs[]:DFS过程中给定节点的深度优先数,即该节点在DFS中被访问的次序 low[]:从给定节点回溯时,节点的low值为从节点在DFS树中的子树中的节点可以回溯到的栈中DFS值最小的节点的dfs值 一个数据结构:栈,用于确定强连通分量 执行过程:对有向图进行深度优先搜索,每抵达一个新节点A就把该节点A入栈,并初始化dfs[A],然后将low[A]初始化为dfs[A]

POJ3180(有向图强连通分量结点数&gt;=2的个数)

The Cow Prom Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1451   Accepted: 922 Description The N (2 <= N <= 10,000) cows are so excited: it's prom night! They are dressed in their finest gowns, complete with corsages and new shoes. T

有向图强连通分量

部分转自 [有向图强连通分量] 有向图中,如果一个子图内任意两点都可达这这个子图为强连通子图 如图所示{1, 2,3,4},{5},{6} 为一个强连通子图 求连通分量 1.用Kosaraju算法(PS:个人感觉Kosaraju算法比较好理解,但是适用范围不如Tarjan算法广) 如果在原图中点 i 可达 点 j 如果图逆向之后,i 依然可以达到 j ,这么可以认为 i 和 j 在同一个强连通分量里 具体算法是 1.先对图进行一次DFS进行标号确定逆向图进行搜索的次序,越接近图的尾部(搜索树的叶

【转载】有向图强连通分量的Tarjan算法

from byvoid [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强连通分量,时间复杂度为

有向图强连通分量的Tarjan算法(转)

原文地址:有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强

有向图强连通分量的Tarjan算法——转自BYVoid

[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强连通分量,时间复杂度为O(N^2+M).更好的

有向图强连通分量的Tarjan算法

有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强连通分量,