这个算法是自己实现的Kosaraju算法,附带一个缩点,其实缩点这个跟Kosaraju算法没有什么关系,应该其他的强连通分量算法计算出每个点所属的强连通分量之后也可以这样缩点。

算法复杂度:

Kosaraju算法:初始化,加边,两次dfs,复杂度O(n+m)

强连通分量缩点算法:遍历每个点每条边,复杂度O(n+m)

对边排序去重:复杂度O(n+mlogm)

注意:

1、最好先 Init() ,然后再 AddEdge()

2、维护缩点时点的性质对新点的影响在 dfs2() 中进行

3、维护缩点时边的性质对新点的影响在 Build() 中进行,特别注意缩点之后的自环

4、并不是每道题都需要原图反图,也并不是都需要对边进行去重

Kosaraju算法缩点的结果本身就是按拓扑序排列的。

namespace SCC {
int n;
vector<int> G[MAXN + 5], BG[MAXN + 5]; int c1[MAXN + 5], cntc1;
int c2[MAXN + 5], cntc2;
int s[MAXN + 5], cnts; int n2;
vector<int> V2[MAXN + 5];
vector<int> G2[MAXN + 5], BG2[MAXN + 5]; void Init(int _n) {
n = _n;
cntc1 = 0, cntc2 = 0, cnts = 0;
for(int i = 1; i <= n; ++i) {
G[i].clear();
BG[i].clear();
c1[i] = 0;
c2[i] = 0;
s[i] = 0;
V2[i].clear();
G2[i].clear();
BG2[i].clear();
}
return;
} void AddEdge(int u, int v) {
G[u].push_back(v);
BG[v].push_back(u);
return;
} void dfs1(int u) {
c1[u] = cntc1;
for(auto &v : G[u]) {
if(!c1[v])
dfs1(v);
}
s[++cnts] = u;
} void dfs2(int u) {
V2[cntc2].push_back(u);
c2[u] = cntc2;
for(auto &v : BG[u]) {
if(!c2[v])
dfs2(v);
}
return;
} void Kosaraju() {
for(int i = 1; i <= n; ++i) {
if(!c1[i]) {
++cntc1;
dfs1(i);
}
}
for(int i = n; i >= 1; --i) {
if(!c2[s[i]]) {
++cntc2;
dfs2(s[i]);
}
}
return;
} void Build() {
n2 = cntc2;
for(int i = 1; i <= n2; ++i) {
for(auto &u : V2[i]) {
for(auto &v : G[u]) {
if(c2[v] != i) {
G2[i].push_back(c2[v]);
BG2[c2[v]].push_back(i);
}
}
}
}
for(int i = 1; i <= n2; ++i) {
sort(G2[i].begin(), G2[i].end());
G2[i].erase(unique(G2[i].begin(), G2[i].end()), G2[i].end());
sort(BG2[i].begin(), BG2[i].end());
BG2[i].erase(unique(BG2[i].begin(), BG2[i].end()), BG2[i].end());
}
return;
} void Solve() {
for(int i = 1; i <= n2; ++i) {
for(auto &u : V2[i]) {
//把原图的信息传递给新图;
}
}
//在新图上Solve;
return;
}
}

好像在不开O2的情况下这个vector版的比链式前向星版的费多了很多时间。

使用方法:

  1. Init,传入原图的点数。
  2. 使用AddEdge逐个加入有向边
  3. 调用Kosaraju划分强连通分量(V2存储强连通缩点后的新点包含原图的哪些点,c2存储原图的点对应强连通缩点后的哪个新点)。
  4. 调用Build在强连通缩点之后的新点之间建立新边到G2,并排序去重。
  5. 在Solve中书写在DAG中求解的代码,例如先把原图的点的信息传递给强连通缩点后的新点,然后在DAG上dp(注意是使用G2)。

模板 - 图论 - 强连通分量 - Kosaraju算法的更多相关文章

  1. 有向图的强连通分量——kosaraju算法

    一.前人种树 博客:Kosaraju算法解析: 求解图的强连通分量

  2. 图论-强连通分量-Tarjan算法

    有关概念: 如果图中两个结点可以相互通达,则称两个结点强连通. 如果有向图G的每两个结点都强连通,称G是一个强连通图. 有向图的极大强连通子图(没有被其他强连通子图包含),称为强连通分量.(这个定义在 ...

  3. 图的强连通分量-Kosaraju算法

    输入一个有向图,计算每个节点所在强连通分量的编号,输出强连通分量的个数 #include<iostream> #include<cstring> #include<vec ...

  4. NOIP专题复习3 图论-强连通分量

    目录 一.知识概述 二.典型例题 1.[HAOI2006]受欢迎的牛 2.校园网络[[USACO]Network of Schools加强版] 三.算法分析 (一)Tarjan算法 (二)解决问题 四 ...

  5. 有向图强连通分量Tarjan算法

    在https://www.byvoid.com/zhs/blog/scc-tarjan中关于Tarjan算法的描述非常好,转述如下: 首先解释几个概念: 有向图强连通分量:在有向图G中,如果两个顶点间 ...

  6. 【模板】强连通分量和tarjan算法

    看了好久才终于明白了这个算法..复杂度是O(n+m). 我觉得这个算法不是很好理解,但是看懂了以后还是觉得听巧妙的. 下面给出模板代码和三组简单数据帮助理解. 代码如下: #include <s ...

  7. 模板 - 强连通分量 - Kosaraju

    Kosaraju算法 O(n+m) vector<int> s; void dfs1(int u) { vis[u] = true; for (int v : g[u]) if (!vis ...

  8. 算法模板——Tarjan强连通分量

    功能:输入一个N个点,M条单向边的有向图,求出此图全部的强连通分量 原理:tarjan算法(百度百科传送门),大致思想是时间戳与最近可追溯点 这个玩意不仅仅是求强连通分量那么简单,而且对于一个有环的有 ...

  9. 强连通分量-----Kosaraju

    芝士: 有向图强连通分量在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connect ...

随机推荐

  1. 父元素设置min-height子元素设置100%问题

    问题:父元素设置min-height子元素高度设置100%取不到值,这是因为子元素 div设置 height:100%: 只有当父级元素满足min-height:1000px;设置的条件才触发: 浏览 ...

  2. 使用springboot实现一个简单的restful crud——02、dao层单元测试,测试从数据库取数据

    接着上一篇,上一篇我们创建了项目.创建了实体类,以及创建了数据库数据.这一篇就写一下Dao层,以及对Dao层进行单元测试,看下能否成功操作数据库数据. Dao EmpDao package com.j ...

  3. 阿里企业邮箱smtp设置

    阿里的邮箱没有SMTP授权码信息 SMTP服务器:smtp.mxhichina.com

  4. js --桥接模式

    定义: 将抽象部分与它的实现部分分离,使他们都可以独立的变化. 也就是说,桥接模式里面有两个角色: - 扩充抽象类 - 具体实现类 在写桥接模式之前,想在写一下关于抽象的理解.我觉得抽象这个概念过于抽 ...

  5. tomcat7:deploy (default-cli) on project myproject: Cannot invoke Tomcat manager: Software caused connection abort: socket write error

    我使用的默认settings.xml,默认的里面只有tomcat6的服务器,没有tomcat7的服务器,接着往下看,下面来验证我的言论 进行tomcat7:run的命令时

  6. (比赛)C - 小Q系列故事——最佳裁判(水题)

    C - 小Q系列故事——最佳裁判 Time Limit:200MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Des ...

  7. 快速为不同 Git 平台配置用户

    在 ~ 目录下创建 config 文件可以为项目配置默认的用户信息,但如果希望经常切换,那么最好就是通过命令为项目单独设置用户. 我使用的 shell 是 zsh, 所以我在 ~/.zshrc 文件中 ...

  8. 大数据技术之Hadoop3.1.2版本HA模式

    大数据技术之Hadoop3.1.2版本HA模式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Hadoop的HA特点 1>.主备NameNode 2>.解决单点故障 ...

  9. Windows性能计数器监控实践

    Windows性能计数器(Performance Counter)是Windows提供的一种系统功能,它能实时采集.分析系统内的应用程序.服务.驱动程序等的性能数据,以此来分析系统的瓶颈.监控组件的表 ...

  10. html实战

    主要html源码 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset=&qu ...