Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >算法模板——Tarjan强连通分量

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

作者头像
HansBug
发布于 2018-04-10 08:49:17
发布于 2018-04-10 08:49:17
62900
代码可运行
举报
文章被收录于专栏:HansBug's LabHansBug's Lab
运行总次数:0
代码可运行

功能:输入一个N个点,M条单向边的有向图,求出此图全部的强连通分量

原理:tarjan算法(百度百科传送门),大致思想是时间戳与最近可追溯点

这个玩意不仅仅是求强连通分量那么简单,而且对于一个有环的有向图可以有效的进行缩点(每个强连通分量缩成一个点),构成一个新的拓扑图(如BZOJ上Apio2009的那个ATM)(PS:注意考虑有些图中不能通过任意一个单独的点到达全部节点,所以不要以为直接tarjan(1)就了事了,还要来个for循环,不过实际上复杂度还是O(M),因为遍历过程中事实上每个边还是只会被走一次^_^)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 type
 2     point=^node;
 3     node=record
 4                g:longint;
 5                next:point;
 6     end;
 7 
 8 var
 9    i,j,k,l,m,n,h,t,ans:longint;
10    ss,s:array[0..100000] of boolean;
11    low,dfn,b,f:array[0..100000] of longint;
12    a:array[0..100000] of point;
13    p:point;
14 function min(x,y:longint):longint;inline;
15          begin
16               if x<y then min:=x else min:=y;
17          end;
18 function max(x,y:longint):longint;inline;
19          begin
20               if x>y then max:=x else max:=y;
21          end;
22 procedure add(x,y:longint);inline;
23           var p:point;
24           begin
25                new(p);
26                p^.g:=y;
27                p^.next:=a[x];
28                a[x]:=p;
29           end;
30 procedure tarjan(x:longint);
31           var i,j,k:longint;p:point;
32           begin
33                inc(h);low[x]:=h;dfn[x]:=h;
34                inc(t);f[t]:=x;s[x]:=true;ss[x]:=true;
35                p:=a[x];
36                while p<>nil do
37                      begin
38                           if not(s[p^.g]) then
39                              begin
40                                   tarjan(p^.g);
41                                   low[x]:=min(low[x],low[p^.g]);
42                              end
43                           else if ss[p^.g] then low[x]:=min(low[x],dfn[P^.g]);
44                           p:=p^.next;
45                      end;
46                if low[x]=dfn[x] then
47                   begin
48                        inc(ans);
49                        while f[t+1]<>x do
50                              begin
51                                   ss[f[t]]:=false;
52                                   b[f[t]]:=ans;
53                                   dec(t);
54                              end;
55                   end;
56           end;
57 begin
58      readln(n,m);
59      for i:=1 to n do a[i]:=nil;
60      for i:=1 to m do
61          begin
62               readln(j,k);
63               add(j,k);
64          end;
65      fillchar(s,sizeof(s),false);
66      fillchar(ss,sizeof(ss),false);
67      fillchar(f,sizeof(f),0);
68      fillchar(low,sizeof(low),0);
69      fillchar(dfn,sizeof(dfn),0);
70      fillchar(b,sizeof(b),0);
71      for i:=1 to n do
72          if s[i]=false then tarjan(i);
73      for i:=1 to n do a[i]:=nil;
74      for i:=1 to n do add(b[i],i);
75      for i:=1 to ans do
76          begin
77               p:=a[i];
78               write('No. ',i,' :');
79               while p<>nil do
80                     begin
81                          write(' ',p^.g);
82                          p:=p^.next;
83                     end;
84               writeln;
85          end;
86      readln;
87 end.
88              
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-02-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
1051: [HAOI2006]受欢迎的牛
1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2410  Solved: 1276 [Submit][Status] Description 每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头牛被所有的牛认为是受欢迎的。 Input 第一行两个数N,M。
HansBug
2018/04/10
6050
Codevs2822 爱在心中
2822 爱在心中  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description “每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动。爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢Our Home。” 在爱的国度里有N个人,在他们的心中都有着一个爱的名单,上面记载着他所爱的人(不会出现自爱的情况)。爱是具有传递性的,即如果A爱B,B爱C,则A也爱C。 如果有这样一部分人,他们彼此都相爱,则他们就超越了一
HansBug
2018/04/10
6290
TarJan 算法求解有向连通图强连通分量
在有向图G中,如果两个 顶点间至少存在一条路径,称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components)。
RainMark
2019/09/10
1.9K0
TarJan 算法求解有向连通图强连通分量
浅析强连通分量 Tarjan
在有向图G中,如果两点互相可达,则称这两个点强连通,如果G中任意两点互相可达,则称G是强连通图。
用户2965768
2019/06/15
8430
Tarjan算法求图的强连通分量
   有向图强连通分量:在有向图 G 中,如果两个顶点 V_i, V_j 间(vi>vj)有一条从 V_i 到 V_j 的有向路径,同时还有一条从 V_j 到 V_i 的有向路径,则称两个顶点强连通 (strongly connected)。如果有向图 G 的每两个顶点都强连通,称 G 是一个强连通图。有向图的极大强连通子图,称为强连通分量 (strongly connected components)。
yhlin
2023/02/27
1.3K0
Tarjan算法求图的强连通分量
Tarjan 算法求解强连通分量
在 《Tarjan 算法的思路》中我们已经给出了 Tarjan 算法中的比较重要的几个元素,我们在这里重新复习一下:
用户2932962
2019/07/27
1.1K0
Kosaraju算法、Tarjan算法分析及证明--强连通分量的线性算法
一、背景介绍 强连通分量是有向图中的一个子图,在该子图中,所有的节点都可以沿着某条路径访问其他节点。强连通性是一种非常重要的等价抽象,因为它满足 自反性:顶点V和它本身是强连通的 对称性:如果顶点V和顶点W是强连通的,那么顶点W和顶点V也是强连通的 传递性:如果V和W是强连通的,W和X是强连通的,那么V和X也是强连通的 强连通性可以用来描述一系列属性,如自然界中物种之间的捕食关系,互相捕食的物种可以看作等价的,在自然界能量传递中处于同一位置。 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,
老白
2018/03/19
2.7K0
Kosaraju算法、Tarjan算法分析及证明--强连通分量的线性算法
POJ2186 Popular Cows 【强连通分量】+【Kosaraju】+【Tarjan】+【Garbow】
Every cow’s dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <= 50,000) ordered pairs of the form (A, B) that tell you that cow A thinks that cow B is popular. Since popularity is transitive, if A thinks B is popular and B thinks C is popular, then A will also think that C is popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow.
全栈程序员站长
2022/07/08
1840
[Tarjan/最大连通分量] P1726 上白泽慧音
在幻想乡,上白泽慧音是以知识渊博闻名的老师。春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄。因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点。人间之里由N个村庄(编号为1..N)和M条道路组成,道路分为两种一种为单向通行的,一种为双向通行的,分别用1和2来标记。如果存在由村庄A到达村庄B的通路,那么我们认为可以从村庄A到达村庄B,记为(A,B)。当(A,B)和(B,A)同时满足时,我们认为A,B是绝对连通的,记为<A,B>。绝对连通区域是指一个村庄的集合,在这个集合中任意两个村庄X,Y都满足<X,Y>。现在你的任务是,找出最大的绝对连通区域,并将这个绝对连通区域的村庄按编号依次输出。若存在两个最大的,输出字典序最小的,比如当存在1,3,4和2,5,6这两个最大连通区域时,输出的是1,3,4。
用户7267083
2022/12/08
3510
[Tarjan/最大连通分量] P1726 上白泽慧音
1589: [Usaco2008 Dec]Trick or Treat on the Farm 采集糖果
1589: [Usaco2008 Dec]Trick or Treat on the Farm 采集糖果 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 419  Solved: 232 [Submit][Status][Discuss] Description 每年万圣节,威斯康星的奶牛们都要打扮一番,出门在农场的N(1≤N≤100000)个牛棚里转悠,来采集糖果.她们每走到一个未曾经过的牛棚,就会采集这个棚里的1颗糖果. 农场不大,所以约翰要想尽法子让奶牛们
HansBug
2018/04/11
5720
367. 学校网络(Tarjan强连通分量)[通俗易懂]
一些学校连接在一个计算机网络上,学校之间存在软件支援协议,每个学校都有它应支援的学校名单(学校 A 支援学校 B,并不表示学校 B 一定要支援学校 A)。
全栈程序员站长
2022/09/22
3720
算法数据结构 | 20行代码实现,使用Tarjan算法求解强连通分量
在开始文章之前先跟大家同步一个坏消息,大概是由于整理了PDF分享的原因,遭到leetcode上海官方投诉侵权(虽然我一直用的都是海外版)。我个人觉得这种行为非常霸道,决定以后不再更新leetcode相关的文章,并且之前的文章也进行了删除。对于想要看这部分文章的朋友,先说声非常抱歉。周末我会寻找其他平台的算法问题作为替代,带来不便,再次抱歉。
TechFlow-承志
2020/09/03
6630
YbtOJ 604「强连通分量」字符变换
小 A 有一个长度为 n 字符串 s,满足 s 中只有 A,B,C,D 四种字符。
yzxoi
2022/09/19
3940
BZOJ1093: [ZJOI2007]最大半连通子图(tarjan dp)
题意 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意 两点u,v,存在一条u到v的有向路径或者从v到u的有向路径。若
attack
2018/09/17
8300
Tarjan算法
tarjan算法 一个关于有向图的联通性的神奇算法。 基于DFS(迪法师)算法,深度优先搜索一张有向图。 名词的储备,有备无患 强连通(strongly connected): 在一个有向图G里,设两个点 a、b。发现,由a有一条路可以走到b,由b又有一条路可以走到a,我们就叫这两个顶点(a,b)强连通。 强连通图(Strongly Connected Graph): 如果在一个有向图G中,每两个点都强连通,我们就叫这个图,强连通图。 强连通分量(strongly connected c
机器学习算法工程师
2018/03/06
8560
Tarjan算法
tarjan算法详解
tarjan算法讲解。 tarjan算法,一个关于 图的联通性的神奇算法。基于DFS算法,深度优先搜索一张有向图。!注意!是有向图。根据树,堆栈,打标记等种种神奇方法来完成剖析一个图的工作。而图的联通性,就是任督二脉通不通。。的问题。 了解tarjan算法之前你需要知道: 强连通,强连通图,强连通分量,解答树(解答树只是一种形式。了解即可) 强连通(strongly connected): 在一个有向图G里,设两个点 a b 发现,由a有一条路可以走到b,由b又有一条路可以走到a,我们就叫这两个顶点(a,
attack
2018/04/12
1.9K0
tarjan算法详解
Tarjan算法
SCC即强连通分量,即一个图的子图,其中的点能相互到达,全称是strongly connected component。
饶文津
2020/06/02
5760
hdu 4635 Strongly connected (tarjan)
题意:给一个n个顶点m条弧的简单有向图(无环无重边),求最多能够加入多少条弧使得加入后的有向图仍为简单有向图且不是一个强连通图。假设给的简单有向图本来就是强连通图,那么输出-1. 分析: 1.用tarjan算法求出强连通分量的个数,假设个数为1,那么输出-1,结束,否则运行2 2.如果将一些强连通分量合并为有n1个顶点简单全然图1,而将剩下的强连通分量合并为n2个顶点的简单全然图2,跨这两个简单全然图的弧的方向仅仅能是单向的,如果m1为全然图1内部的弧的数量,m2为为全然图2内部的弧的数量。m3为跨这两个简单全然图的弧的数量,那么 ans=n1*(n1-1)-m1+n2*(n2-1)-m2+n1*n2-m3 —————————————————-1式 n1+n2=n —————————————————-2式 m1+m2+m3=m —————————————————-3式 n*n=(n1+n2)(n1+n2)=n1*n1+n2*n2+2*n1*n2 —————————————————–4式 所以 ans=n*n-m-n-n1*n2=n*n-m-n-n1*(n-n1) ans要最大,所以n1*(n-n1)要最小。同一时候要跨图1。图2的弧要单向, 所以在跨图1,图2的弧要单向的情况下。n1尽量小。
全栈程序员站长
2022/07/08
2090
图论--SCC强连通缩点--Tarjan
强连通缩点与双连通缩点大同小异,也就是说将强连通分支缩成一个点之后,没有强连通,成为有向无环图,在对图进行题目的操作。
风骨散人Chiam
2020/10/28
5740
有向图强连通分量SCC(全网最好理解)
在有向图中,如果一些顶点中任意两个顶点都能互相到达(间接或直接),那么这些顶点就构成了一个强连通分量,如果一个顶点没有出度,即它不能到达其他任何顶点,那么该顶点自己就是一个强连通分量。
风骨散人Chiam
2020/10/28
1.4K0
有向图强连通分量SCC(全网最好理解)
相关推荐
1051: [HAOI2006]受欢迎的牛
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验