某国有n个城市,为了使得城市间的交通更便利,该国国王打算在城市之间修一些高速公路,由于经费限制,国王打算第一阶段先在部分城市之间修一些单向的高速公路。 现在,大臣们帮国王拟了一个修高速公路的计划。看了计划后,国王发现,有些城市之间可以通过高速公路直接(不经过其他城市)或间接(经过一个或多个其他城市)到达,而有的却不能。如果城市A可以通过高速公路到达城市B,而且城市B也可以通过高速公路到达城市A,则这两个城市被称为便利城市对。 国王想知道,在大臣们给他的计划中,有多少个便利城市对。
个人使用,可能不是很详细 强联通分量 这里的dfn可以写成low 因为都是在栈中,只要保证该节点的low值不为本身即可 void tarjan(int now) { dfn[now]=low[now]=++tot; s.push(now); vis[now]=1; for(int i=headE[now];i!=-1;i=E[i].nxt) { if(!dfn[E[i].v]) tarjan(E[i].v),low[now]=
在有向图G中,如果两个 顶点间至少存在一条路径,称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components)。
说到以Tarjan命名的算法,我们经常提到的有3个,其中就包括本文所介绍的求强连通分量的Tarjan算法。而提出此算法的普林斯顿大学的Robert E Tarjan教授也是1986年的图灵奖
若low[v]>dfn[u],则(u,v)为割边。但是实际处理时我们并不这样判断,因为有的图上可能有重边,这样不好处理。我们记录每条边的标号(一条无向边拆成的两条有向边标号相同),记录每个点的父亲到它的边的标号,如果边(u,v)是v的父亲边,就不能用dfn[u]更新low[v]。这样如果遍历完v的所有子节点后,发现low[v]=dfn[v],说明u的父亲边(u,v)为割边。
转载自Tarjan算法 LCA问题(Least Common Ancestors,最近公共祖先问题),是指给定一棵有根树T,给出若干个查询LCA(u, v)(通常查询数量较大),每次求树T中两个顶点u和v的最近公共祖先,即找一个节点,同时是u和v的祖先,并且深度尽可能大(尽可能远离树根)。 LCA问题有很多解法:线段树、Tarjan算法、跳表、RMQ与LCA互相转化等。本文主要讲解Tarjan算法的原理及详细实现。 一 LCA问题 LCA问题的一般形式:给定一棵有根树,给出若干个查询,每个查询要求指定节点u
有向图强连通分量:在有向图 G 中,如果两个顶点 V_i, V_j 间(vi>vj)有一条从 V_i 到 V_j 的有向路径,同时还有一条从 V_j 到 V_i 的有向路径,则称两个顶点强连通 (strongly connected)。如果有向图 G 的每两个顶点都强连通,称 G 是一个强连通图。有向图的极大强连通子图,称为强连通分量 (strongly connected components)。
LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点。 换句话说,就是两个点在这棵树上距离最近的公共祖先节点。 所以LCA主要是用来处理当两个点仅有唯一一条确定的最短路径时的路径。 有人可能会问:那他本身或者其父亲节点是否可以作为祖先节点呢? 答案是肯定的,很简单,按照人的亲
在之前的 《客户端基本不用的算法系列:从 floodfill 到图的连通性》一文中,我们已经了解了在无向图中的割点和桥的定义。
在有向图G中,如果两点互相可达,则称这两个点强连通,如果G中任意两点互相可达,则称G是强连通图。
一、背景介绍 强连通分量是有向图中的一个子图,在该子图中,所有的节点都可以沿着某条路径访问其他节点。强连通性是一种非常重要的等价抽象,因为它满足 自反性:顶点V和它本身是强连通的 对称性:如果顶点V和顶点W是强连通的,那么顶点W和顶点V也是强连通的 传递性:如果V和W是强连通的,W和X是强连通的,那么V和X也是强连通的 强连通性可以用来描述一系列属性,如自然界中物种之间的捕食关系,互相捕食的物种可以看作等价的,在自然界能量传递中处于同一位置。 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,
这一篇博客继续以一些OJ上的题目为载体,对图的连通性专题进行整理一下。会陆续的更新。。。
该文介绍了如何通过tarjan算法求出图中所有割点,并统计割点数。首先介绍了什么是割点,然后说明了如何利用tarjan算法求出所有割点并统计割点数。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1269 一道判断强连通图的裸题,强连通图就是图中任意两点之间可以相互到达,直接用tarja
tarjan算法讲解。 tarjan算法,一个关于 图的联通性的神奇算法。基于DFS算法,深度优先搜索一张有向图。!注意!是有向图。根据树,堆栈,打标记等种种神奇方法来完成剖析一个图的工作。而图的联通性,就是任督二脉通不通。。的问题。 了解tarjan算法之前你需要知道: 强连通,强连通图,强连通分量,解答树(解答树只是一种形式。了解即可) 强连通(strongly connected): 在一个有向图G里,设两个点 a b 发现,由a有一条路可以走到b,由b又有一条路可以走到a,我们就叫这两个顶点(a,
若为根,有两个及以上孩子算割点,不为根,点u存在连接的一个点v访问的最小值low[v]大于等于(等于就是最后还是走到这个点)dfn[u],则u为割点
tarjan算法 一个关于有向图的联通性的神奇算法。 基于DFS(迪法师)算法,深度优先搜索一张有向图。 名词的储备,有备无患 强连通(strongly connected): 在一个有向图G里,设两个点 a、b。发现,由a有一条路可以走到b,由b又有一条路可以走到a,我们就叫这两个顶点(a,b)强连通。 强连通图(Strongly Connected Graph): 如果在一个有向图G中,每两个点都强连通,我们就叫这个图,强连通图。 强连通分量(strongly connected c
2023-02-13:力扣数据中心有 n 台服务器,分别按从 0 到 n-1 的方式进行了编号
这道题本质上就是要搞懂 无根树上任意两点距离就是 各自到根节点距离之和再减去两倍的lca节点到根节点距离
题目背景 割点 题目描述 给出一个n个点,m条边的无向图,求图的割点。 输入输出格式 输入格式: 第一行输入n,m 下面m行每行输入x,y表示x到y有一条边 输出格式: 第一行输出割点个数 第二行按照节点编号从小到大输出节点,用空格隔开 输入输出样例 输入样例#1: 6 7 1 2 1 3 1 4 2 5 3 5 4 5 5 6 输出样例#1: 1 5 说明 n,m均为100000 tarjan 图不一定联通!!! 割点真是一个非常神奇的东西。 虽然和tarjan很像, 而且能理解其中的奥秘。 但
今天字节笔试的第二题,详情由于保密协议不能上网,但是大意就是给一大堆节点,去求LCA。递归直接爆栈,用stack写递归有一个点,改进优化了一下有两个点…… 我印象中这个算法挺简单的,就搜了一下,果然找到了。不是,现在校招算法题都这么丧病了吗。 由于保密协议,不能放代码。后面放Tarjan算法学习笔记。
强连通缩点与双连通缩点大同小异,也就是说将强连通分支缩成一个点之后,没有强连通,成为有向无环图,在对图进行题目的操作。
POJ 2762 Going from u to v or from v to u? 题意:判断该图的任意两点是否可达 分析:tarjan后进行缩点,缩点后再建图,判断该图是否为单链式图形(只有一个叶
a,a',b,b'分别表示两对夫妇,如果a,b有矛盾,那么a要来,就只能来b',b要来,就只能来a'。于是建了两条边(a,b'),(b,a')。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
功能:输入一个N个点,M条单向边的有向图,求出此图全部的强连通分量 原理:tarjan算法(百度百科传送门),大致思想是时间戳与最近可追溯点 这个玩意不仅仅是求强连通分量那么简单,而且对于一个有环的有向图可以有效的进行缩点(每个强连通分量缩成一个点),构成一个新的拓扑图(如BZOJ上Apio2009的那个ATM)(PS:注意考虑有些图中不能通过任意一个单独的点到达全部节点,所以不要以为直接tarjan(1)就了事了,还要来个for循环,不过实际上复杂度还是O(M),因为遍历过程中事实上每个边还是只会被走一次
前言 在图论中,除了在有向图中的强连通分量,在无向图中还有一类双联通分量 双联通分量一般是指点双连通分量 当然,还有一种叫做边双连通分量 边双联通分量 对于一个连通图,如果任意两点至少存在两条“边不重复”的路径,则说图是点双连通的,边双连通的极大子图称为边双连通分量。 边双联通分量的计算方法比较简单 类比tarjan求强联通分量的算法,唯一的区别在于不能沿着dfs过来的那条边走回去。 也就是说在tarjan的时候我们需要记录一下父亲节点 其余的就和普通的tarjan一样啦 例题 割边(桥) 割边:对于无向图
先对这个图跑tarjan,对于每个强联通点,有sum[i],然后把原来的边都删了。
现在有 N 头牛,编号从 1 到 N,给你 M 对整数 (A,B),表示牛 A 认为牛 B 受欢迎。
// tarjan算法求无向图的桥、边双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; const int SIZE = 100010; int head[SIZE], ver[SIZE * 2], Next[SIZE * 2]; int dfn[SIZE], low[SIZE], c[SIZE]; int n, m,
题目背景 割点 题目描述 给出一个n个点,m条边的无向图,求图的割点。 输入输出格式 输入格式: 第一行输入n,m 下面m行每行输入x,y表示x到y有一条边 输出格式: 第一行输出割点个数 第二行按照节点编号从小到大输出节点,用空格隔开 输入输出样例 输入样例#1 6 7 1 2 1 3 1 4 2 5 3 5 4 5 5 6 输出样例#1: 1 5 说明 n,m均为100000 tarjan 图不一定联通!!! tarjan求割点, 若 ,说明从v不能走回u之前的点 那么u一定能将v与之前的点分割开
2822 爱在心中 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description “每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动。爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢Our Home。” 在爱的国度里有N个人,在他们的心中都有着一个爱的名单,上面记载着他所爱的人(不会出现自爱的情况)。爱是具有传递性的,即如果A爱B,B爱C,则A也爱C。 如果有这样一部分人,他们彼此都相爱,则他们就超越了一
链接:https://pan.baidu.com/s/1yuII_btZspV5GVhAtlcl0Q 提取码:vvfn
求割点(无向边): 所谓的割点,就是删除某个点,图便不连通了。 POJ 1523 #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int MN=1111; struct Edge { int to,next; }edge[MN<<2]; int dfn[MN]; int low[MN]; int head[MN<<2]; int subnet[MN]; int E,tp,ro
// Tarjan算法求有向图强连通分量并缩点 /*强连通缩点与双连通缩点大同小异,也就是说将强连通分支缩成一个点之后,没有强连通,成为有向无环图,在对图进行题目的操作。*/ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<queue> using namespace std; const int N = 100010, M = 1000010; int v
输入格式 第一行包含三个正整数 N,M,SN,M,S,分别表示树的结点个数、询问的个数和树根结点的序号。
Description A network administrator manages a large network. The network consists of N computers and M links between pairs of computers. Any pair of computers are connected directly or indirectly by successive links, so data can be transformed between any
Description Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a failure of a single node, 3, in the network on the left would prevent some of the still avai
强连通分量(Strongly Connected Component,SCC)指的是有向图中的一个最大子图,该子图内的任意两个顶点均可达。要找到所有的强连通分量,可以使用Tarjan算法。
Kosaraju算法,其实与tarjan算法差不多。但是码量较小,容易记忆。其时间复杂度与tarjan算法一样,为O(n+m),所以,某种程度上来说Kosaraju可以替代tarjan算法。
SCC即强连通分量,即一个图的子图,其中的点能相互到达,全称是strongly connected component。
在开始文章之前先跟大家同步一个坏消息,大概是由于整理了PDF分享的原因,遭到leetcode上海官方投诉侵权(虽然我一直用的都是海外版)。我个人觉得这种行为非常霸道,决定以后不再更新leetcode相关的文章,并且之前的文章也进行了删除。对于想要看这部分文章的朋友,先说声非常抱歉。周末我会寻找其他平台的算法问题作为替代,带来不便,再次抱歉。
题目链接:http://acm.pku.edu.cn/JudgeOnline/problem?id=1986 这是一道并查集+树的题,采用Tarjan离线算法 首先BS一下出题的人,也太懒了吧,还要我
#include<iostream> #include<stdio.h> #include<vector> using namespace std; const int maxn=100010; int head[maxn],ver[maxn*2],Next[maxn*2]; int dfn[maxn],low[maxn],sta[maxn]; int n,m,tot,num,root; bool cut[maxn]; void add(int x,int y) { ver[++tot]=y;
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <vector> #include <map> #include <stack> using namespace std; const int N=100010; int head[N],ver[N*2],Next[N*2]; int dfn[N],low[N],n,m,tot,num; bool brige[N*2]; void ad
领取专属 10元无门槛券
手把手带您无忧上云