各色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算法求出 ...
随机推荐
- Linux的磁盘管理和进程管理(入门)
查看磁盘使用情况 df :列出文件系统整体的磁盘使用量 增加-h参数可以使得显示的容量更人性化 du:检查磁盘空间使用量---需要进入文件中查看 挂载本地磁盘或文件 mount mount /dev/ ...
- Jquery遍历复选框选中项
var ret=''; $('name=chkIds').each(function(){ if($(this).is(':checked')){ ret+=$(this).val()+','; } ...
- Java进阶练习题整理(1)
1. 检查时异常.非检查时异常.运行时异常. Throwable是一切异常.错误类的超类,Throwable有两个子类,Error(错误)和Exception(异常).Exception异常又分为Ru ...
- vue菜单切换
HTML: <div id="box"> <ul> <li v-for= "(item,index) in arry"> & ...
- postman怎么调中文
事先准备 1 安装好postman. 下载网址:https://www.postman.com/downloads/ 2 下载好app.zip中文压缩包,下载地址:https://wws.lanzou ...
- selenium元素定位之 八大元素定位
进入网站,按F12,点击弹出框右上角的位置的小箭头,然后移到需要定位的元素上,点击一下即可定位元素(1) id定位(有id才可以定位)wd.find_element_by_id('') #输入id属性 ...
- Alibaba-技术专区-RocketMQ 延迟消息实现原理和源码分析
痛点背景 业务场景 假设有这么一个需求,用户下单后如果30分钟未支付,则该订单需要被关闭.你会怎么做? 之前方案 最简单的做法,可以服务端启动个定时器,隔个几秒扫描数据库中待支付的订单,如果(当前时间 ...
- SpringBoot开发十一-显示登录信息
需求介绍-显示登录信息 我们需要在每个页面的头部都要把登录用户的头像显示出来,另外在详细信息里面你需要显示用户的名字,除此之外如果登录了,我们显示首页 信息 头像 三个功能的链接,否则显示首页 登录两 ...
- Ajax 局部刷新 异步提交
AJAX简介 局部刷新,异步提交. AJAX 不是新的编程语言,而是一种使用现有标准的新方法.它最大的有点就是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容. 浏览器朝后端发送请 ...
- noip36
开场先看一遍题面,凭着错误的感觉t3叫naive是一个原因,312开局.然后就死的很惨. T1 朴素暴力40pts,细想就有80pts,然而我只写了十分钟左右就爬回T3了,所以... 其实都是借口 正 ...