各色Tarjan集合
#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集合的更多相关文章
- Tarjan算法详解理解集合
[功能] Tarjan算法的用途之一是,求一个有向图G=(V,E)里极大强连通分量.强连通分量是指有向图G里顶点间能互相到达的子图.而如果一个强连通分量已经没有被其它强通分量完全包含的话,那么这个强连 ...
- tarjan讲解(用codevs1332(tarjan的裸题)讲解)
主要借助这道比较裸的题来讲一下tarjan这种算法 tarjan是一种求解有向图强连通分量的线性时间的算法.(用dfs来实现) 如果两个顶点可以相互通达,则称两个顶点强连通.如果有向图G的每两个顶点都 ...
- POJ 1236 Network of Schools(Tarjan缩点)
Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 16806 Accepted: 66 ...
- Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】
一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...
- 【POJ 3062】Party(2-SAT、tarjan)
2-SAT的入门题. a,a',b,b'分别表示两对夫妇,如果a,b有矛盾,那么a要来,就只能来b',b要来,就只能来a'.于是建了两条边(a,b'),(b,a'). 用tarjan强连通分量缩点染色 ...
- (转载)LCA问题的Tarjan算法
转载自:Click Here LCA问题(Lowest Common Ancestors,最近公共祖先问题),是指给定一棵有根树T,给出若干个查询LCA(u, v)(通常查询数量较大),每次求树T中两 ...
- 强连通分量的Tarjan算法
资料参考 Tarjan算法寻找有向图的强连通分量 基于强联通的tarjan算法详解 有向图强连通分量的Tarjan算法 处理SCC(强连通分量问题)的Tarjan算法 强连通分量的三种算法分析 Tar ...
- Code[VS] 1332 题解 【Kosaraju】【Tarjan】
Code[VS] 1332 上白泽慧音题解 Tarjan Algorithm Kosaraju Algorithm 题目传送门:http://codevs.cn/problem/1332/ 题目描 ...
- UVAoj 11324 - The Largest Clique(tarjan + dp)
题意:给定一个有向图,寻找一个点数最大集合,使得这个集合中的任意两个点 u,v, 都有u->v 或者 v->u 或者u<==>v 思路:首先将强连通分量通过tarjan算法求出 ...
随机推荐
- 自建简易FaaS平台
近些年来,传统的 IaaS.PaaS 已经无法满足人们对资源调度的需求了.各大云厂商相继开始推出自家的 Serverless 服务.Serverless 顾名思义,它是"无服务器" ...
- Windows协议 LDAP篇 - 组&OU
LDAP搜索 LDAP查找 位操作 以userAccountControl为例,CN=User-Account-Control,CN=Schema,CN=Configuration,DC=muxue, ...
- springboot整合javafx
原文(原码)参考地址: https://github.com/roskenet/springboot-javafx-support https://github.com/spartajet/javaf ...
- PaddlePaddle之猫狗大战(本地数据集)
新手入门PaddlePaddle的一个简单Demo--猫狗大战 主要目的在于整体了解PP用卷积做图像分类的流程,以及最最重要的掌握自定义数据集的读取方式 猫狗数据集是从网络上下载到工作目录的. 本项目 ...
- 操作系统思考 第十一章 C语言中的信号量
第十一章 C语言中的信号量 作者:Allen B. Downey 原文:Chapter 11 Semaphores in C 译者:飞龙 协议:CC BY-NC-SA 4.0 信号量是学习同步的一个好 ...
- Linux进程理解与实践(一)基本概念和编程概述(fork,vfork,cow)
进程 and 程序 什么是程序? 程序是完成特定任务的一系列指令集合. 什么是进程? [1]从用户的角度来看:进程是程序的一次执行过程 [2]从操作系统的核心来看:进程是操作系统分配的内存.CPU时间 ...
- 用SamInside破解Windows登录密码
用小马PE的USB-HDD+格式制作启动优盘: 笔记本启动时按ESC键,选择USB启动: 进入WinPE后,将%SystemRoot%/system32/config全部拷贝出来(WinXP这个文件夹 ...
- Notes about "Exploring Expect"
Chapter 3 Section "The expect Command": expect_out(0,string) can NOT be written as "e ...
- LinuxDHCP配置
目录 一.DHCP服务 1.1.了解DHCP服务 1.2.使用DHCP的好处 1.3.DHCP的分配方式 1.4.DHCP的租约过程 客户机请求IP地址 重新登录 更新租约 1.5.使用DHCP动态配 ...
- Docker与k8s的恩怨情仇(八)——蓦然回首总览Kubernetes
在系统介绍了如何实际部署一个K8S项目后,作为本系列文章的最后一篇,我们一起来看看Kubernetes集群内容总览,再对一些更深层次的功能进行总结. Kubernetes总览 下图是一个k8s的总览结 ...