#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. chanakya

    仅供个人娱乐 参考http://www.saulgoodman.cn/HA-Chanakya.html 靶机信息 https://www.vulnhub.com/entry/ha-chanakya,3 ...

  2. 题解 P6688 可重集

    己所欲者,杀而夺之,亦同天赐 解题思路 一定不要用自动溢出的 Hash!!!!!!! 我真的是调吐了... 思路非常简单明了 : 需要我们创新一下 Hash. 首先我们的 Hash 要满足无序性.. ...

  3. kivy八种布局方式学习

    kivy八种布局:FloatLayout.BoxLayout.AnchorLayout.GridLayout.PageLayout.RelativeLayout.ScatterLayout.Stack ...

  4. Java面向对象11——多态

    多态  package oop.demon01.demon06; ​ public class Application {     public static void main(String[] a ...

  5. [WesternCTF2018]shrine(SSTI+过滤)

    记一道存在过滤的模板注入的题.直接给源代码 import flask import os app = flask.Flask(__name__) app.config['FLAG'] = os.env ...

  6. C++ //关系运算符重载 < = > !=

    1 //关系运算符重载 < = > != 2 #include <iostream> 3 #include <string> 4 using namespace s ...

  7. 线程礼让_yield

    线程礼让_yield 礼让线程,让当前正在执行的线程暂停,但不阻塞 将线程从运行状态转为就绪状态 让cpu重新调度,礼让不一定成功!看CPU心情 测试案例: package multithreadin ...

  8. 客户端连接mysql数据库反应慢

    远程客户端连接MysqL数据库太慢解决方案 局域网客户端访问mysql 连接慢问题解决 编辑mysql配置文件 # vi my.conf [mysqld] skip-name-resolve 重启my ...

  9. 嵌入式ARM汇编详解

    文章目录 零.预备知识 1.ARM与X86 2.ARM中指令的执行 3.ARM的九种寻址方式 立即数寻址 寄存器寻址 寄存器间接寻址 寄存器偏移寻址 寄存器基址变址寻址 批量寄存器寻址 相对寻址 堆栈 ...

  10. SQL 练习12

    查询和" 01 "号的同学学习的课程 完全相同的其他同学的信息 分析 如果某同学学的某一个课程和01同学所学的课程有对应,那么子查询返回false. 如果没有对应,子查询返回tru ...