#include<bits/stdc++.h>
using namespace std;
const int N=100000,M=200000;
//所有Tarjan都要:
// dfn[N],low[N],cnt=1,st,scc,zhan[N],top,前向星,vector<int>SCC[N]
//强连通 ,belong[N],inq[N]
//割边,边双 bridge[N], belong[N]
//点双,割点 cut[N],root
int dfn[N],low[N],cnt=1,zhan[N],top,st,belong[N],scc,head[N],root,n;
bool bridge[M],inq[N],cut[N];
vector <int>SCC[N];
struct bian
{
int nxt,to;
}b[M];
void add(int from,int to)
{
b[++cnt].nxt=head[from];
b[cnt].to=to;
head[from]=cnt;
}
void Tarjan1(int cur)//强连通
{
dfn[cur]=low[cur]=++st;
zhan[++top]=cur;inq[cur]=true;
int i=head[cur],v;
while(i!=0)
{
v=b[i].to;
if(dfn[v]==0)
{
Tarjan1(v);
low[cur]=min(low[cur],low[v]);
}
else
{
if(inq[v]==true)
{
low[cur]=min(low[cur],dfn[v]);
}
}
i=b[i].nxt;
}
if(low[cur]==dfn[cur])
{
scc++;
int ding;
do
{
ding=zhan[top];
inq[ding]=false;
zhan[top--]=0;
belong[ding]=scc;
SCC[scc].push_back(ding);
}while(ding!=cur);
}
}
void Tarjan2(int cur,int pre)//割边,边双
{
dfn[cur]=low[cur]=++st;
zhan[++top]=cur;
int i=head[cur],v;
while(i!=0)
{
v=b[i].to;
if(i!=pre)
{
if(dfn[v]==0)
{
Tarjan2(v,i^1);
low[cur]=min(low[cur],low[v]);
if(low[v]>dfn[cur])
{
bridge[i]=bridge[i^1]=true;
scc++;
int ding;
do
{
ding=zhan[top];
zhan[top--]=0;
belong[ding]=scc;
SCC[scc].push_back(ding);
}while(ding!=v);
}
}
else
low[cur]=min(low[cur],dfn[v]);
}
i=b[i].nxt;
}
}
void Tarjan3(int cur)
{
dfn[cur]=low[cur]=++st;
zhan[++top]=cur;
int i=head[cur],v,child=0;
while(i!=0)
{
v=b[i].to;
if(dfn[v]==0)
{
child++;
Tarjan3(v);
low[cur]=min(low[cur],low[v]);
if(low[v]>=dfn[cur])
{
if(root!=cur)
cut[cur]=true;
scc++;
int ding;
do
{
ding=zhan[top];
zhan[top--]=0;
SCC[scc].push_back(ding);
}while(ding!=v);
SCC[scc].push_back(cur);
}
}
else
low[cur]=min(low[cur],dfn[v]);
i=b[i].nxt;
}
if(cur==root&&child>=2)
{
cut[cur]=true;
}
}
int main()
{
for(int i=1;i<=n;i++)
{
if(dfn[i]==0)
Tarjan1(i);
if(dfn[i]==0)
{
Tarjan2(i,0);
int ding;
while(top>0)
{
ding=zhan[top];
zhan[top--]=0;
SCC[scc].push_back(ding);
}
}
if(dfn[i]==0)
root=i,Tarjan3(i);
}
return 0;
}

特殊点:
强连通的出栈在函数末,进入条件low[cur]=dfn[cur],break条件ding!=cur,注意要维护是否在栈中的数组inq,dfn[v]!=0且inq[v]==true时,才能进入else语句中更新low[cur];

边双和割边出栈在Tarjan过程中的dfn[v]=0中,判断是low[v]>dfn[cur],break条件ding!=v,结束后要清栈;

割点和点双联通在Tarjan过程中的dfn[v]=0中,判断是low[v]>=dfn[cur],break条件ding!=v,注意求割点时,若cur=root且child>=2,为割点;

各色Tarjan集合的更多相关文章

  1. Tarjan算法详解理解集合

    [功能] Tarjan算法的用途之一是,求一个有向图G=(V,E)里极大强连通分量.强连通分量是指有向图G里顶点间能互相到达的子图.而如果一个强连通分量已经没有被其它强通分量完全包含的话,那么这个强连 ...

  2. tarjan讲解(用codevs1332(tarjan的裸题)讲解)

    主要借助这道比较裸的题来讲一下tarjan这种算法 tarjan是一种求解有向图强连通分量的线性时间的算法.(用dfs来实现) 如果两个顶点可以相互通达,则称两个顶点强连通.如果有向图G的每两个顶点都 ...

  3. POJ 1236 Network of Schools(Tarjan缩点)

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16806   Accepted: 66 ...

  4. Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】

    一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...

  5. 【POJ 3062】Party(2-SAT、tarjan)

    2-SAT的入门题. a,a',b,b'分别表示两对夫妇,如果a,b有矛盾,那么a要来,就只能来b',b要来,就只能来a'.于是建了两条边(a,b'),(b,a'). 用tarjan强连通分量缩点染色 ...

  6. (转载)LCA问题的Tarjan算法

    转载自:Click Here LCA问题(Lowest Common Ancestors,最近公共祖先问题),是指给定一棵有根树T,给出若干个查询LCA(u, v)(通常查询数量较大),每次求树T中两 ...

  7. 强连通分量的Tarjan算法

    资料参考 Tarjan算法寻找有向图的强连通分量 基于强联通的tarjan算法详解 有向图强连通分量的Tarjan算法 处理SCC(强连通分量问题)的Tarjan算法 强连通分量的三种算法分析 Tar ...

  8. Code[VS] 1332 题解 【Kosaraju】【Tarjan】

    Code[VS] 1332 上白泽慧音题解 Tarjan Algorithm Kosaraju Algorithm 题目传送门:http://codevs.cn/problem/1332/   题目描 ...

  9. UVAoj 11324 - The Largest Clique(tarjan + dp)

    题意:给定一个有向图,寻找一个点数最大集合,使得这个集合中的任意两个点 u,v, 都有u->v 或者 v->u 或者u<==>v 思路:首先将强连通分量通过tarjan算法求出 ...

随机推荐

  1. Django < 2.0.8 任意URL跳转漏洞(CVE-2018-14574)

    影响版本 Django < 2.0.8 抓包 访问http://192.168.49.2:8000//www.example.com,即可返回是301跳转到//www.example.com

  2. LAMP介绍以及Apache安装

    一.LAMP架构介绍 1.1 LAMP概述 LAMP架构是目前成熟的企业网站应用模式之一,指的是协同工作的一整套系统和相关软件,能够提供动态Web站点服务及其应用开发环境.LAMP是一个缩写词,具体包 ...

  3. 关于document.write()方法重绘页面问题

    学习的时候,document.write()被告知是用来将内容写进页面里面,同时也被告知document.write()方法会重绘页面,但是关于什么时候会重绘,什么时候不会重绘页面没有太多解释. 首先 ...

  4. 利用MySQL原数据信息批量转换指定库数据表生成Hive建表语句

    1.写出文件工具类 package ccc.utile; import java.io.*; /** * @author ccc * @version 1.0.0 * @ClassName Write ...

  5. TotalCommander的两款目录插件

    CatalogMaker 与 DiskDir Extended 是两个用于生成文件夹目录的totalCmd插件. 将指定目录下所有文件.文件夹以指定格式存储在一个文本文件中,可作为EverCD+的轻量 ...

  6. Git-09-常用命令

    git常用命令 一般来说,日常使用只要记住下图6个命令,就可以了.但是熟练使用,恐怕要记住60-100个命令 下面是我整理的常用 Git 命令清单.几个专用名词的译名如下. Workspace:工作区 ...

  7. 【笔记】衡量线性回归法的指标 MSE,RMS,MAE以及评价回归算法 R Square

    衡量线性回归法的指标 MSE,RMS,MAE以及评价回归算法 R Square 衡量线性回归法的指标 对于分类问题来说,我们将原始数据分成了训练数据集和测试数据集两部分,我们使用训练数据集得到模型以后 ...

  8. P5038 奇怪的游戏

    题目询问了一个不能确定的时间,所以显然做法中要包含一个二分答案. 我们将整张图分为黑白点两种,黑点旁边的点就是白点,白点旁边的点就是黑点,想一下就能知道,每次操作会使黑白点的数字各加一,而我们的目的就 ...

  9. msp432搭建平衡小车(二)

    前言 上一节掌握了使用pwm驱动电机,接下来介绍如何使用msp432读取mpu6050数据 正文 首先我们得知道mpu6050通信方式,由于mpu6050只能用i2c通信,所以学会使用msp432的i ...

  10. C# 获取计算机的硬件、操作系统信息

    C# 获取计算机的硬件.操作系统信息   获得信息的命名空间是:System.Management 创建ManagementObjectSearcher对象获取相关信息 eg: using Syste ...