Tarjan算法(模板)
算法思想: 首先要明确强连通图的概念,一个有向图中,任意两个点互相可以到达;什么是强连通分量?有向图的极大连通子图叫强连通分量。
给一个有向图,我们用Tarjan算法把这个图的子图(在这个子图内,任意两个点可以相互到达,极大的子图)缩成一个点,相当于化简;
怎样去做:从一个点开始遍历它能走到的下一个点(dfn记录时间戳,low记录能回到的最早的时间戳),每遍历到一个点,判断这个点如果没有走过(dfn值为零),继续深搜,如果走过了并且在栈里面说明可以形成一个环(那就可以缩成一个点,更新当前点low的值,回到更早的时间戳),搜完它可以到达所有的点以后回溯,更新low;直到回到 low[u]==dfn[u](环的“根节点"),出栈这个点上面的所有的点(包括这个点本身,他们可以缩成一个点).继续回溯.
特别注意:
else if(instack[v])/*走过并且形成一个环??????*/
low[u]=min(low[u],dfn[v]);/*更新最小值low,合并集合*/
/*不能写成low[u]=min(low[v],low[u])*/
当计算有多少个强连通分量的时候,写成那个没关系,但是如果是求割点,两个语句求出来的low值不一样,值会偏小,割点判断错误(因为判断条件是if(low[v]>=dfn[u]))。
扩展:
计算出入度,问加多少条边可以变成一个整个连通分量:
在这里首先缩点,用一个color[ ]数组,将同一集合的点标记成某个序号(出栈的时候就是同一集合),最后遍历输入的边,用两个数组标记每一个集合的出度入度情况,得出入度和出度分别有几个集合为零,输出最大值。注意:调用tarjan函数的时候,用for循环,因为图可能不连通!还有当它本来就是一个连通分量的时候,特判一下。
例题:POJ 1236
Network of Schools
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
#define N 1010
vector<int>edge[N];
vector<int>belong[N];
stack<int>s;
int low[N];/*所属的强连通数组*/
int dfn[N];/*访问的顺序*/
bool instack[N];/*是否在栈内*/
int n,m,u,v,cnt,cntb;/*n个顶点,m条边*/
void Tarjan(int u)/*当前处于的节点*/
{
++cnt;/*计算访问到第几个点(时间戳)*/
dfn[u]=low[u]=cnt;/*访问的顺序(时间戳),low数组记录这个点所能回到的最早的时间戳*/
s.push(u);
instack[u]=true;
for(int i=0;i<edge[u].size();i++)/*下一个要走的节点*/
{
int v=edge[u][i];
if(!dfn[v])/*如果没走过*/
{
Tarjan(v);/*深搜*/
low[u]=min(low[u],low[v]);/*更新最小值low,合并集合*/
}
else if(instack[v])/*走过并且形成一个环??????*/
low[u]=min(low[u],dfn[v]);/*更新最小值low,合并集合*/
}
if(dfn[u]==low[u])/*回到环的起点,出栈*/
{
++cntb;
int node;
do
{
node=s.top();
s.pop();
instack[node]=false;
belong[cntb].push_back(node);/*将集合分组*/
}while(node!=u);
}
}
int main()
{
memset(instack,0,sizeof(instack));
cnt=0;cntb=0;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
edge[u].push_back(v);
}
Tarjan(1);/*从一号顶点开始遍历*/
for(int i=1;i<=n;i++)
printf("dfn:%d low:%d\n",dfn[i],low[i]);
for(int i=1;i<=cntb;i++)
{
printf("第%d组\n",i);
for(int j=0;j<belong[i].size();j++)
printf("%d ",belong[i][j]);
printf("\n");
}
return 0;
}
/*
7 11
1 2
2 3
2 5
2 4
3 5
3 7
7 5
5 6
6 7
4 1
4 5
*/
Tarjan算法(模板)的更多相关文章
- Tarjan 算法&模板
Tarjan 算法 一.算法简介 Tarjan 算法一种由Robert Tarjan提出的求解有向图强连通分量的算法,它能做到线性时间的复杂度. 我们定义: 如果两个顶点可以相互通达,则称两个顶点强连 ...
- HDU 2586 ( LCA/tarjan算法模板)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:n个村庄构成一棵无根树,q次询问,求任意两个村庄之间的最短距离 思路:求出两个村庄的LCA,d ...
- tarjan算法模板
终于能自己完整的打下来 #include<cstdio> #include<cstring> #include<iostream> #include<vect ...
- poj1236 Tarjan算法模板 详解
思想: 做一遍DFS,用dfn[i]表示编号为i的节点在DFS过程中的访问序号(也可以叫做开始时间)用low[i]表示i节点DFS过程中i的下方节点所能到达的开始时间最早的节点的开始时间.初始时dfn ...
- Tarjan算法模板(USACO03FALL受欢迎的牛)
好文章 #include<bits/stdc++.h> using namespace std; const int N = 10010, M = 50010; int n, m; int ...
- 有向图的强联通分量 Tarjan算法模板
//白书 321页 #include<iostream> #include<cstdio> #include<cstring> #include<vector ...
- 割点的tarjan算法模板
基本思路: 朴素的思想是删除每一个点,然后去dfs,这样无疑会爆炸 换一种思路,怎样判断是割点呢,如果是根节点的话毫无疑问只要看子树的数目,但是如果不是根节点呢,不知大牛是怎样想到的 利用两个数组df ...
- POJ1236_A - Network of Schools _强连通分量::Tarjan算法
Time Limit: 1000MS Memory Limit: 10000K Description A number of schools are connected to a compute ...
- 一直想写的关于tarjan算法的理解——向struct edge大佬低头
tarjan的算法精髓就是dfn[]和low[]数组 dfn[i]表示在该节点被搜索的次序(时间戳) low[i]表示i或i的子树可以追溯到的最早的栈中节点 判断有强连通分量的条件就是 dfn[i]= ...
随机推荐
- web博客
欢迎大家来戳一戳
- swoole(2)swoole进程结构
一:进程基本概念 系统中正在运行的一个程序,程序一旦运行就是进程 一个进程可以拥有多个线程 核心内容分为两部分:内存(进程创建时从系统分配的,它所创建的变量都会存储在这一块内存中).上下文环境 二:s ...
- 06.深入浅出 Spring Boot - 数据访问之Druid
代码下载:https://github.com/Jackson0714/study-spring-boot.git 一.Druid是什么? 1.Druid是数据库连接池,功能.性能.扩展性方面都算不错 ...
- 从String到==和hashcode
public static void main(String[] args) { String s1 = "ni"; String s2 = "hao"; St ...
- java中的while循环和do while循环
那么在讲解循环之前呢我们先来了解一下什么是循环 生活中的例子 车子的轮胎他就是一直在循环 马拉松跑到也是在循环 因为运动员不停的一圈一圈在跑这也是一个循环 那么我们为什么要学习循环呢? 下面看一个 ...
- Java easyui 下拉框默认选中第一个
html代码: <tr> <td> <div style="margin-bottom:5px">计价方式: <%--下拉框默认选中第 ...
- SpringBoot框架——从SpringBoot看IoC容器初始化流程之方法分析
目录 一.概观Spring Boot 二.Spring Boot应用初始化 2.1 初始化入口 2.2 SpringApplication的run方法 2.3 方法分析 三.容器创建与初始化 3.1 ...
- 深入理解“骑士”漏洞 VoltJockey
先理解一下题目:VoltJockey: Breaching TrustZone by Software-Controlled Voltage Manipulation over Multi-core ...
- 聊一聊 React 中的 CSS 样式方案
和 Angular,Vue 不同,React 并没有如何在 React 中书写样式的官方方案,依靠的是社区众多的方案.社区中提供的方案有很多,例如 CSS Modules,styled-compone ...
- Spring框架——继承 - 依赖 - 命名空间
Spring 继承 子 bean 可以继承⽗ bean 的属性值. <bean id="user" class="com.sunjian.entity.User&q ...