题目描述

›对于一个有向图顶点的子集S,如果在S内任取两个顶点u和v,都能找到一条从u到v的路径,那么就称S是强连通的。如果在强连通的顶点集合S中加入其他任意顶点集合后,它都不再是强连通的,那么就称S是原图的一个强连通分量(SCC: Strongly Connected Component)。任意有向图都可以分解成若干不相交的强连通分量,这就是强连通分量分解。把分解后的强连通分量缩成一个顶点,就得到了一个DAG(有向无环图)。
现在,请求一个有向图中强连通分量的个数

输入

第一行两个数V,E,表示顶点数和边数

接下来E行,两个数s,t,描述一条有向边

输出

强连通分量的个数

求强联通分量当然可以暴力,不过慢一些

今天我们讲讲tarjan算法(更快解决您的需求哦= ̄ω ̄=)

首先我们需要2个数组,1个数组是时间戳(dns),用于判断某点是否是某强联通分量的起点

另一个数组是low,用于记录某点属于哪一个强联通分量。

在我们遍历每个点时,初始状态就是dns[i]=low[i]=++tot;//tot为目前遍历点的编号

接下来我们利用链表寻找下一个点

如果这个点还未被访问那么我们就访问他tarjan(g[i].to);

如果我们已经访问了这个点,那我们判断一下它是否在栈内(没错!tarjan算法利用的就是栈)

如果在栈内(如果不在栈内那么不属于一个强联通分量,不用更新low数组),则更新low数组(保证low数组最小)low[i]=min(low[i],low[g[i].to]);

最后我们判断一下如果low[i]=dns[i]即该点为此次查找的强连通分量的起点

然后我们查找在它之后进栈的元素,让他们出站,答案+1;

当然,有些图不只一个连通图

所以我们要每一个点都遍历一遍,如果没有便历过,那么就进行tarjan

由于每一个点都进栈一次,出栈一次

所以最坏复杂度为O(n+m)

下面贴代码(终于打完了。。手残。。)

#include<cstdio>
inline int read()
{
int x=;char c;
while((c=getchar())<''||c>'');
for(;c>=''&&c<='';c=getchar())x=x*+c-'';
return x;
}
#define MN 10000
#define MM 50000
struct edge{int nx,t;}e[MM+];
int h[MN+],en,d[MN+],l[MN+],cnt,z[MN+],zn,inz[MN+],K;
inline void ins(int x,int y){e[++en]=(edge){h[x],y};h[x]=en;}
void tj(int x)
{
d[x]=l[x]=++cnt;inz[z[zn++]=x]=;
for(int i=h[x];i;i=e[i].nx)
{
if(!d[e[i].t])tj(e[i].t);
if(inz[e[i].t]&&l[e[i].t]<l[x])l[x]=l[e[i].t];
}
if(d[x]==l[x])for(++K;z[zn]!=x;)inz[z[--zn]]=;
}
int main()
{
int n,m,i;
n=read();m=read();
while(m--)i=read(),ins(i,read());
for(i=;i<=n;++i)if(!d[i])tj(i);
printf("%d",K);
}

下面贴代码

强联通分量(tarjan算法+算法简介)的更多相关文章

  1. 强联通分量-tarjan算法

    定义:在一张有向图中,两个点可以相互到达,则称这两个点强连通:一张有向图上任意两个点可以相互到达,则称这张图为强连通图:非强连通图有极大的强连通子图,成为强联通分量. 如图,{1},{6}分别是一个强 ...

  2. 强联通分量之kosaraju算法

    首先定义:强联通分量是有向图G=(V, E)的最大结点集合,满足该集合中的任意一对结点v和u,路径vu和uv同时存在. kosaraju算法用来寻找强联通分量.对于图G,它首先随便找个结点dfs,求出 ...

  3. [vios1023]维多利亚的舞会3<强联通分量tarjan>

    题目链接:https://vijos.org/p/1023 最近在练强联通分量,当然学的是tarjan算法 而这一道题虽然打着难度为3,且是tarjan算法的裸题出没在vijos里面 但其实并不是纯粹 ...

  4. POJ 3592 Instantaneous Transference(强联通分量 Tarjan)

    http://poj.org/problem?id=3592 题意 :给你一个n*m的矩阵,每个位置上都有一个字符,如果是数字代表这个地方有该数量的金矿,如果是*代表这个地方有传送带并且没有金矿,可以 ...

  5. 有向图的强联通分量 Tarjan算法模板

    //白书 321页 #include<iostream> #include<cstdio> #include<cstring> #include<vector ...

  6. POJ 3114 Countries in War(强联通分量+Tarjan)

    题目链接 题意 : 给你两个城市让你求最短距离,如果两个城市位于同一强连通分量中那距离为0. 思路 :强连通分量缩点之后,求最短路.以前写过,总感觉记忆不深,这次自己敲完再写了一遍. #include ...

  7. hdu 1269 (强联通分量Tarjan入门)

    迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  8. Tarjan 算法求割点、 割边、 强联通分量

    Tarjan算法是一个基于dfs的搜索算法, 可以在O(N+M)的复杂度内求出图的割点.割边和强联通分量等信息. https://www.cnblogs.com/shadowland/p/587225 ...

  9. 【强联通图 | 强联通分量】HDU 1269 迷宫城堡 【Kosaraju或Tarjan算法】

      为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A房间和B房间,只说明 ...

随机推荐

  1. Codeforces Round #481 (Div. 3) 全题解

    A题,题目链接:http://codeforces.com/contest/978/problem/A 解题心得:题意就是让你将这个数列去重,重复的数只保留最右边的那个,最后按顺序打印数列.set+m ...

  2. EVALUation mode running with code size limit:2k keil进行仿真过程中出现的报错

    EVALUation mode running with code size limit:2k 如果keil软件未破解,会限制程序的存储大小.第一是你的软件没有破解,不能编译2K以上的程序:这种情况下 ...

  3. P3365 改造二叉树

    P3365 改造二叉树 链接 分析: 求出中序遍历后,然后使其变成上升子序列.过程:每个点减去坐标,然后nlogn求出最长不下降子序列,n-ans即答案. 做题时一直认为二叉树就是完全二叉树,然后一直 ...

  4. P2370 yyy2015c01的U盘

    P2370 yyy2015c01的U盘 题目背景 在2020年的某一天,我们的yyy2015c01买了个高端U盘. 题目描述 你找yyy2015c01借到了这个高端的U盘,拷贝一些重要资料,但是你发现 ...

  5. MyEclipse - MyEclipse优化

    1.去除不需要的启动加载项 选择菜单:Window --> Preferences -->General --> Startup and Shutdown, 可以关掉的启动项有: J ...

  6. 云计算之路-阿里云上:OCS问题的进展以及11:30-11:50遇到的问题

    (上图是今天出问题期间Web服务器性能监控图,紫色表示的是Request Execution Time) 昨天我们发布了一篇博客分享了我们这两天遇到的OCS(开放缓存服务)问题,详见云计算之路-阿里云 ...

  7. ansible自动安装jdk

    脚本功能:安装jdk 测试环境:CentOS6.7 说明: 1.卸载系统自带的openjdk,重新安装Oracle jdk,支持Hotspot,性能更好,更稳定. 2.jdk软件包按文档说明进行定制( ...

  8. 使用dib element proliant-tools制作deploy image

    element proliant-tools会在ipa ramdisk中安装一个rpm包hpssacli(HP的RAID管理工具),和一个python module proliantutils(里面P ...

  9. [18/12/3]蓝桥杯 练习系统 入门级别 Fibonacci数列求模问题 题解思路

    前言略. 看到这个题目本来应该很高兴的,因为什么,因为太TM的基础了啊! 可是当你用常规方法尝试提交OJ时你会发现..hhh...运行超时..(开心地摇起了呆毛 //Fibonacci数列递归一般问题 ...

  10. 系统编程--高级IO

    1.非阻塞I/O 非阻塞I/O使我们可以调用不会永远阻塞的I/O操作,例如open,read和write.如果这种操作不能完成,则立即出错返回,表示该操作如继续执行将继续阻塞下去.对于一个给定的描述符 ...