【原创】tarjan算法初步(强连通子图缩点)

tarjan算法的思路不是一般的绕!!(不过既然是求强连通子图这样的回路也就可以稍微原谅了。。)

但是研究tarjan之前总得知道强连通分量是什么吧。。

上百度查查:

  有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量(strongly connected components)。

看不懂。。那么——

看这张图

其中从1可以到2,3,4,5,6;

从2可以到1,3,4,5,6;

从3可以到6;

从4可以到1,2,3,5,6;

从5可以到1,2,3,4,6;

从6哪儿都到不了。

我们发现,{1,2,4,5}两两可以互达,我们称其为原图的一个强连通子图,而{3},{6}各自单独为原图的另外两个强连通子图。

我们想要通过程序实现O(n)求所有强连通子图,就要用到tarjan算法。

程序代码如下(tarjan的主要思路写在程序注释里,若无法理解请参考另一篇【转载】全网最!详!细!tarjan算法讲解):

 // Tarjan有向图强连通缩点
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<string>
#define MAXV 10010
#define MAXE 100010
using namespace std;
struct tEdge{
int np;
tEdge *next;
}E[MAXE],*V[MAXV];
int tope=-;
int n,m;
int dfn[MAXV],dfstime=; // dfn[i]表示点i的dfs序
int low[MAXV]; // low[i]表示目前点i所能到达的最小dfs序点
int status[MAXV]; // status[i]表示点i的访问状态,0=未访问,1=访问中,2=访问完毕
int stack[MAXV],tops=-;
int color[MAXV],totc=; // color[]表示缩点后的块
void addedge(int u,int v){
E[++tope].np=v;
E[tope].next=V[u];
V[u]=&E[tope];
}
void tarjan(int now){
stack[++tops]=now; // 进栈
low[now]=dfn[now]=++dfstime; // 初始化dfs序
status[now]=; // 访问中(在栈中)
for(tEdge *ne=V[now];ne;ne=ne->next){
if(status[ne->np]==){ // 未访问(没有进过栈)
tarjan(ne->np); // dfs往下进行递归访问
low[now]=min(low[now],low[ne->np]);
// 由于now可达ne->np,故ne->np可达的最小dfs序点从now也可达
}
else if(status[ne->np]==){ // 回边,发现ne->np为栈中元素
low[now]=min(low[now],dfn[ne->np]);
// 若ne->np的dfs序比原来now可达的最小dfs序还小则更新
}
}
if(low[now]==dfn[now]){
// now到达的最小dfs序为自己dfs序
// 即now不包含在最小dfs序更小的缩点中
// 而栈中now以后的节点若不能到达now则早已出栈(FILO)
totc++; // 申请新颜色(一种颜色代表一个缩点)
while(stack[tops+]!=now){ // 栈中所有在now之后的节点都在该缩点内
status[stack[tops]]=; // 访问完毕(已出栈)
color[stack[tops--]]=totc; // 为节点染色
}
}
}
int main(){
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(status,,sizeof(status));
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
}
for(int i=;i<=n;i++)
if(status[i]==)
tarjan(i); // 图不连通时必须保证每个点都处理到
for(int i=;i<=n;i++)
printf("Point %d colored %d\n",i,color[i]); // 输出所属强连通块编号
return ;
}

测试数据:


运行结果:

Point  colored
Point colored
Point colored
Point colored
Point colored
Point colored

即color[1]={6},color[2]={3},color[3]={1,2,4,5}为原图的3个强连通子图的缩点。

【原创】tarjan算法初步(强连通子图缩点)的更多相关文章

  1. Tarjan算法分解强连通分量(附详细参考文章)

    Tarjan算法分解强连通分量 算法思路: 算法通过dfs遍历整个连通分量,并在遍历过程中给每个点打上两个记号:一个是时间戳,即首次访问到节点i的时刻,另一个是节点u的某一个祖先被访问的最早时刻. 时 ...

  2. tarjan算法(强连通分量 + 强连通分量缩点 + 桥(割边) + 割点 + LCA)

    这篇文章是从网络上总结各方经验 以及 自己找的一些例题的算法模板,主要是用于自己的日后的模板总结以后防失忆常看看的, 写的也是自己能看懂即可. tarjan算法的功能很强大, 可以用来求解强连通分量, ...

  3. Tarjan算法初步

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

  4. Tarjan在图论中的应用(一)——用Tarjan来实现强连通分量缩点

    前言 \(Tarjan\)是一个著名的将强连通分量缩点的算法. 大致思路 它的大致思路就是在图上每个联通块中任意选一个点开始进行\(Tarjan\)操作(依据:强连通分量中的点可以两两到达,因此从任意 ...

  5. [学习笔记] Tarjan算法求强连通分量

    今天,我们要探讨的就是--Tarjan算法. Tarjan算法的主要作用便是求一张无向图中的强连通分量,并且用它缩点,把原本一个杂乱无章的有向图转化为一张DAG(有向无环图),以便解决之后的问题. 首 ...

  6. HDU 1269 迷宫城堡 tarjan算法求强连通分量

    基础模板题,应用tarjan算法求有向图的强连通分量,tarjan在此处的实现方法为:使用栈储存已经访问过的点,当访问的点离开dfs的时候,判断这个点的low值是否等于它的出生日期dfn值,如果相等, ...

  7. Tarjan算法【强连通分量】

    转自:byvoid:有向图强连通分量的Tarjan算法 Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树.搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断 ...

  8. Tarjan 算法求 LCA / Tarjan 算法求强连通分量

    [时光蒸汽喵带你做专题]最近公共祖先 LCA (Lowest Common Ancestors)_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili tarjan LCA - YouTube Tarj ...

  9. 【算法】Tarjan算法求强连通分量

    概念: 在有向图G中,如果两个定点u可以到达v,并且v也可以到达u,那么我们称这两个定点强连通. 如果有向图G的任意两个顶点都是强连通的,那么我们称G是一个强连通图. 一个有向图中的最大强连通子图,称 ...

随机推荐

  1. sklearn数据集

    数据集划分: 机器学习一般的数据集会划分为两个部分 训练数据: 用于训练,构建模型 测试数据: 在模型检验时使用,用于评估模型是否有效 sklearn数据集划分API: 代码示例文末! scikit- ...

  2. NIT校赛-- 雷顿女士与分队

    题意:https://ac.nowcoder.com/acm/contest/2995/D 思路: 和最大子串很像,dp[i]=max(dp[i-1]+a[i],a[i]),要不和前面连一起,要不就是 ...

  3. ingress之tls和path使用

    ingress tls 上节课给大家展示了 traefik 的安装使用以及简单的 ingress 的配置方法,这节课我们来学习一下 ingress tls 以及 path 路径在 ingress 对象 ...

  4. Spring集成kafka,消费者运行时内存占用会一直增长

    Spring集成kafka,消费者运行时内存占用会一直增长? 20C 本人用Spring集成kafka消费者,发布运行时内存占用会一直升高,最后程序挂掉.请各位大神看看,提供解决方法 以下是我的配置文 ...

  5. System.Data.EntityException: The underlying provider failed on Open.

    场景:IIS默认站点建立程序,使用Windows集成身份验证方式,连接SQLServer数据库也是采用集成身份验证.我报“System.Data.EntityException: The underl ...

  6. Sql语句知识大全

    1.经典SQL语句大全(绝对的经典) 2. 3. 4.一.基础 1.1.说明:创建数据库 2.CREATE DATABASE database-name 3.2.说明:删除数据库 4.drop dat ...

  7. Unsupported major.minor version 52.0错误和 jdbc odbc

    什么是JDBC? JDBC, 全称为Java DataBase Connectivity standard, 它是一个面向对象的应用程序接口(API), 通过它可访问各类关系数据库.JDBC也是jav ...

  8. iOS UIControl 事件的说明(转)

    在控件事件中,简单解释下下面几个事件. 说明:由于是在“iOS 模拟器”中测试的,所以不能用手指,只能用鼠标. 1)UIControlEventTouchDown 指鼠标左键按下(注:只是“按下”)的 ...

  9. win10下 安装迅雷精简版

    下载链接:https://files-cdn.cnblogs.com/files/del88/ThunderMini_1.5.3.288.zip 他妈的 今天安装迅雷精简版 在win10上 竟然报错, ...

  10. Nginx笔记一

      nginx: 为什么选择nginx: nginx是一个高性能的web和反向代理服务器. 作为web服务器:使用更少的资源,支持更多的并发连接,更高的效率,能够支持高达5w个并发连接数的相应, 作为 ...