1、简介:

在阅读下列内容之前,请务必了解 图论相关概念 中的基础部分。

强连通的定义是:有向图 G 强连通是指,G 中任意两个结点连通。

强连通分量(Strongly Connected Components,SCC)的定义是:极大的强连通子图。

这里要介绍的是如何来求强连通分量。

2、引入:

在介绍该算法之前,先来了解 DFS 生成树,我们以下面的有向图为例:

3、算法思想:

求强连通分量就相当于求(或类似于环可以一遍又一遍无限走下去,切走不出这个环)的个数。

其他人博客上说什么:树边(tree edge),横叉边(cross edge),反祖边(back edge),前向边(forward edge),这些太复杂了,对像我一样的蒟蒻不友好以下是一段简洁的解释。

先说算法步骤:

1、我们要对一张图(有向图)进行遍历。

记录:dfn[x]:   存x点的时间戳(是第几个遍历这个点的),(相当于记录了遍历的顺序);

low[x]:   存x点最早能访问到的时间戳。

2、思考:若dfn[x]=low[x],就说明x点无论怎么走,都无法到达时间戳更靠前的点,证明x点是一个环的开始(环顶)。

3、将遍历到的点依次入栈,当判断到环顶时,栈中的点就是一个强连通分量。

4、详细步骤:

  • 一个结点的子树内结点的 dfn 都大于该结点的 dfn。
  • 从根开始的一条路径上的 dfn 严格递增,low 严格非降。

按照深度优先搜索算法搜索的次序对图中所有的结点进行搜索,维护每个结点的 dfn 与 low 变量,且让搜索到的结点入栈。每当找到一个强连通元素,就按照该元素包含结点数目让栈中元素出栈。在搜索过程中,对于结点  和与其相邻的结点  不是  的父节点)考虑 3 种情况:

  1.  v未被访问:继续对 v 进行深度搜索。在回溯过程中,用 low[v] 更新 。因为存在从 u 到 v 的直接路径,所以说 v 能够回溯到的已经在栈中的结点,u 也一定能够回溯到。
  2.  v被访问过,已经在栈中:根据 low 值的定义,用 dfn[v] 或low[v] 更新 low[u] 
  3.  v被访问过,已不在栈中:说明v已搜索完毕,其所在连通分量已被处理,所以不用对其做操作。

5、例题:(洛谷 P2863 [USACO06JAN] The Cow Prom S)

//洛谷 P2863 [USACO06JAN] The Cow Prom S
#include<bits/stdc++.h>
using namespace std;
const int N=2e4+2,M=5e4+2;
int n,m,dfn[N],low[N],first[N],stk[N],siz[N],top=0,tot=0,cnt=0,ans=0;
bool in[N];
struct node{int v,ne;}e[M];
void add(int u,int v){
e[++tot]={v,first[u]};
first[u]=tot;
}
void tarjan(int u){ //tarjan算法求强连通分量
dfn[u]=low[u]=++tot;
in[u]=1; //表示u点在栈中
stk[++top]=u; //将u记入栈中
for(int i=first[u];i;i=e[i].ne){
int v=e[i].v;
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]); //更新low[u]值的意义是让u点不提前出栈
}
else if(in[v]) low[u]=min(low[u],low[v]);
}
if(low[u]==dfn[u]){
int y;
++cnt;
do{
y=stk[top--];in[y]=0;
siz[cnt]++;
}while(u!=y);
}
}
int main(){
scanf("%d%d",&n,&m);
int u,v;
for(int i=1;i<=m;++i){
scanf("%d%d",&u,&v);
add(u,v); //建单向边
}
for(int i=1;i<=n;++i) if(!dfn[i]) tarjan(i); //图有可能不连通,存在几个分开的图
for(int i=1;i<=cnt;++i) if(siz[i]>1) ans++; //siz[]记录每一个强连通分量的大小
printf("%d",ans);
return 0;
}

Tarjan强连通分量详解的更多相关文章

  1. Tarjan 强连通分量 及 双联通分量(求割点,割边)

    Tarjan 强连通分量 及 双联通分量(求割点,割边) 众所周知,Tarjan的三大算法分别为 (1)         有向图的强联通分量 (2)         无向图的双联通分量(求割点,桥) ...

  2. tarjan 强连通分量

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

  3. tarjan强连通分量模板(pascal)

    友好城市 [问题描述]小 w 生活在美丽的 Z 国. Z 国是一个有 n 个城市的大国, 城市之间有 m 条单向公路(连接城市 i. j 的公路只能从 i 连到 j). 城市 i. j 是友好城市当且 ...

  4. 1051: [HAOI2006]受欢迎的牛 (tarjan强连通分量+缩点)

    题目大意:CodeVs2822的简单版本 传送门 $Tarjan$强连通分量+缩点,若连通块的个数等于一则输出n:若缩点后图中出度为0的点个数为1,输出对应连通块内的点数:否则输出0: 代码中注释部分 ...

  5. 洛谷 P2746 [USACO5.3]校园网Network of Schools schlnet Tarjan强连通分量

    schlnet ★★★   输入文件:schlnet.in   输出文件:schlnet.out   简单对比时间限制:1 s   内存限制:128 MB 描述 一些学校连入一个电脑网络.那些学校已订 ...

  6. [poj 2553]The Bottom of a Graph[Tarjan强连通分量]

    题意: 求出度为0的强连通分量. 思路: 缩点 具体有两种实现: 1.遍历所有边, 边的两端点不在同一强连通分量的话, 将出发点所在强连通分量出度+1. #include <cstdio> ...

  7. [poj 1904]King's Quest[Tarjan强连通分量]

    题意:(当时没看懂...) N个王子和N个女孩, 每个王子喜欢若干女孩. 给出每个王子喜欢的女孩编号, 再给出一种王子和女孩的完美匹配. 求每个王子分别可以和那些女孩结婚可以满足最终每个王子都能找到一 ...

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

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

  9. Equivalent Sets HDU - 3836 2011多校I tarjan强连通分量

    题意: 给一些集合 要求证明所有集合是相同的 证明方法是,如果$A∈B$,$B∈A$那么$A=B$成立 每一次证明可以得出一个$X∈Y$ 现在已经证明一些$A∈B$成立 求,最少再证明多少次,就可以完 ...

  10. Codeforces Round #244 (Div. 2) C. Checkposts (tarjan 强连通分量)

    题目:http://codeforces.com/problemset/problem/427/C 题意:给你n座城市,m条有向道路,然后有一个机制,你在某一个城市设置检查点,那么被设置的检查点受保护 ...

随机推荐

  1. CF1442D Sum

    题意 有 \(n\) 个不降的非负整数数组,每个数组可以不取或取一个前缀,总共要取 \(k\) 个元素,问取到的和最大多少. 题解 结论题,但是想到结论还不会. 首先,我们只会有一个数组没选完,其它要 ...

  2. Dotnet9网站回归Blazor重构,访问速度飞快,交互也更便利了!

    大家好,我是沙漠尽头的狼. Dotnet9网站回归Blazor重构,访问速度确实飞快,同时用上Blazor的交互能力,站长也同步添加了几个在线工具,这篇文章分享下Blazor的重构过程,希望对大家网站 ...

  3. ProtocolBuffers的国际化和本地化支持

    目录 1. 引言 2. 技术原理及概念 3. 实现步骤与流程 4. 应用示例与代码实现讲解 5. 优化与改进 34.< Protocol Buffers 的国际化和本地化支持> 本文将介绍 ...

  4. 利用身份验证和授权机制,例如OAuth、JWT 和 API 密钥,APIaaS 如何帮助解决安全挑战?

    什么是 APIaaS? APIaaS,即 API 即服务(API as a Service)是一种创新的基于云的方法,提供 API(应用程序编程接口),使第三方服务提供商能够访问特定服务.数据或资源. ...

  5. Visual Studio Code安装C#开发工具包并编写ASP.NET Core Web应用

    前言 前段时间微软发布了适用于VS Code的C#开发工具包(注意目前该包还属于预发布状态但是可以正常使用),因为之前看过网上的一些使用VS Code搭建.NET Core环境的教程看着还挺复杂的就一 ...

  6. 理解ASP.NET Core - 限流(Rate Limiting)

    注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 概述 在微服务化的架构设计中,网关扮演着重要的看门人角色,它所提供的功能之一就是限流.而对于众 ...

  7. 模拟ArrayList(顺序表)的底层实现

    模拟ArrayLIst的底层实现 package com.tedu.api04.list; import java.util.Objects; /** * @author LIGENSEN * Dat ...

  8. Nextcloud登录界面输入用户名和密码后报内部故障

    查询~/nextcloud/data/nextcloud.log,找到日志报出如下错误 "Something is wrong with your openssl setup: error: ...

  9. Linux 文件系统的设计

    一 硬盘的最小存储单元是扇区,扇区大小为512B 文件系统将硬盘划分为固定大小的块(block),最常见的块大小为4KB 块是文件系统读写硬盘的最小单位 二 文件系统设计面临的基本问题: 用户怎么找到 ...

  10. Docker版SS安装

    灰常简单 首先安装docker 使用官方安装脚本自动安装 64位的centos7和8安装命令如下: curl -fsSL https://get.docker.com | bash -s docker ...