模板 - 强连通分量 - Kosaraju】的更多相关文章

Kosaraju算法 O(n+m) vector<int> s; void dfs1(int u) { vis[u] = true; for (int v : g[u]) if (!vis[v]) dfs1(v); s.push_back(u); } void dfs2(int u) { color[u] = sccCnt; for (int v : g2[u]) if (!color[v]) dfs2(v); } void Kosaraju() { s.clear(); for (int i…
这个算法是自己实现的Kosaraju算法,附带一个缩点,其实缩点这个跟Kosaraju算法没有什么关系,应该其他的强连通分量算法计算出每个点所属的强连通分量之后也可以这样缩点. 算法复杂度: Kosaraju算法:初始化,加边,两次dfs,复杂度O(n+m) 强连通分量缩点算法:遍历每个点每条边,复杂度O(n+m) 对边排序去重:复杂度O(n+mlogm) 注意: 1.最好先 Init() ,然后再 AddEdge() 2.维护缩点时点的性质对新点的影响在 dfs2() 中进行 3.维护缩点时边…
芝士: 有向图强连通分量在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.有向图的极大强连通子图,称为强连通分量. 如图中1,2,3,4是一个强连通分量. Kosaraju算法: 如果这是一个无向图,那么从一个节点出发,深搜得到的所有节点都是连通的. 但这是一个有向图,起始节点的不同会导致结果的不同,举个栗子,从5搜…
http://poj.org/problem?id=2186 题意: 一个有向图,求出点的个数(任意点可达). 思路: Kosaraju算法的第一次dfs是后序遍历,而第二次遍历时遍历它的反向图,从标号最大的结点开始遍历. 对于这道题,在求解强连通分量之后,能被所有点可达只可能是最后一个强连通块,根据遍历时的拓扑序,我们可以计算出最后一个的结点个数. 但是我们最后还是要判断一下,这个连通块是不是任意结点可达. #include<iostream> #include<algorithm&g…
一.前人种树 博客:Kosaraju算法解析: 求解图的强连通分量…
输入一个有向图,计算每个节点所在强连通分量的编号,输出强连通分量的个数 #include<iostream> #include<cstring> #include<vector> using namespace std; ; struct Edge{ int go,next; }; ,book[maxn]; vector<int> S; vector<int> G[maxn],G2[maxn]; void dfs(int u) { vis[u]=…
int dfn[N], low[N], dfncnt, s[N], tp; int scc[N], sc; // 结点 i 所在 scc 的编号 int sz[N]; // 强连通 i 的大小 void tarjan(int u) { low[u] = dfn[u] = ++dfncnt, s[++tp] = u; for(int i = h[u]; i; i = e[i].nex) { const int &v = e[i].t; if(!dfn[v]) tarjan(v), low[u] =…
#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> using namespace std; ; ; inline int read(){ ; ; char x = getchar(); '<x){ ; x=getchar(); } '){ a=(a<<)+(a<<)+x-'; x=ge…
[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强连通分量,时间复杂度为O(N^2+M).更好的…
求有向图的强连通分量     Kosaraju算法可以求出有向图中的强连通分量个数,并且对分属于不同强连通分量的点进行标记. (1) 第一次对图G进行DFS遍历,并在遍历过程中,记录每一个点的退出顺序.以下图为例: G图 结点第二次被访问即为退出之时,那么我们可以得到结点的退出顺序 (2)倒转每一条边的方向,构造出一个反图G’.然后按照退出顺序的逆序对反图进行第二次DFS遍历.我们按1.4.2.3.5的逆序第二次DFS遍历: G`图   访问过程如下: 每次遍历得到的那些点即属于同一个强连通分量…