首页 > 其他分享 >tarjan 各类板子集合

tarjan 各类板子集合

时间:2024-03-13 14:58:01浏览次数:26  
标签:tarjan int bi 板子 ++ dfn low 集合

tarjan大板子(非讲解):

1、普通缩点DGA

void tarjan(int x){
	dfn[x]=low[x]=++cntp;
	q.push(x);v[x]=1; 
	for(int i=head[x];i;i=bi[i].next){
		int j=bi[i].to;
		if(!dfn[j]){
			tarjan(j);
			low[x]=min(low[x],low[j]);
		}
		else if(v[j])low[x]=min(low[x],dfn[j]);
	}
	if(low[x]==dfn[x]){
		int p;
		num++;//缩点的个数 
		do{
			p=q.top();
			q.pop();
			zh[p]=num;//zh[i]表示 i对应的缩点之后的点 
			cntt[num]++;//cntt[i]表示缩点之后i点代表的点的个数 
			v[p]=0;
		}while(x!=p);
	}
}
//重建边 很多题需要缩点重建边成一个DGA以后在进行操作
for(int i=1;i<=cnt;i++){
	if(zh[bi[i].fr]!=zh[bi[i].to])ad(zh[bi[i].fr],zh[bi[i].to]);
}

2、求割点

void tarjan(int x,int root){
	dfn[x]=low[x]=++cntp;
	int fl=0;
	for(int i=head[x];i;i=bi[i].next){
		int j=bi[i].to;
		if(!dfn[j]){
			tarjan(j);
			low[x]=min(low[x],low[j]);
			if(low[j]>=dfn[x]){
				fl++;
				if(x!=root||fl>1)ge[x]=1;
			}
		}
		else low[x]=min(low[x],dfn[j]);
	}
}

3、求割边

void tarjan(int x,int id){
	dfn[x]=low[x]=++cntp;
	for(int i=head[x];i!=-1;i=bi[i].next){
		int j=bi[i].to;
		if(!dfn[j]){
			tarjan(j,i);
			low[x]=min(low[x],low[j]);
			if(low[j]>dfn[x])bb[i]=bb[i^1]=1;//注意边要从0或2开始存
		}
		else if(i!=(id^1))low[x]=min(low[x],dfn[j]);
	}
}

4、求点双连通分量

void tarjan(int x,int id){
	dfn[x]=low[x]=++cntp;
	q.push(x);
	for(int i=head[x];i!=-1;i=bi[i].next){
//		cout<<i<<' '<<id<<endl;
		if(i==(id^1))continue;
		int j=bi[i].to;
		if(!dfn[j]){
			tarjan(j,i);
			low[x]=min(low[x],low[j]);
		}
		else low[x]=min(low[x],dfn[j]);
	}
	if(dfn[x]==low[x]){和父亲的边是割边,和栈里在他上面的点在一个边双连通分量里面。
		num++;
		int p;
		do{
			p=q.top();
			q.pop();
			zh[p]=num;
		}while(p!=x);
	}
}

5、点双连通分量

void tarjan(int x){
	dfn[x]=low[x]=++cntp;
	int fl=0;
	for(int i=head[x];i;i=bi[i].next){
		int j=bi[i].to;
		if(!dfn[j]){
			q.push(j);
			tarjan(j);
			low[x]=min(low[x],low[j]);
			if(low[j]>=dfn[x]){
				num++;
				int p;
				do{
					p=q.top();
					q.pop();
					mann[num].ps(p);
				}while(p!=j);
				mann[num].ps(x);
			}
		}
		else low[x]=min(low[x],dfn[j]);
	}
}

END

标签:tarjan,int,bi,板子,++,dfn,low,集合
From: https://www.cnblogs.com/GGrun-sum/p/18070631

相关文章

  • P1621 集合题解
    题目Caima给你了所有[a,b]范围内的整数。一开始每个整数都属于各自的集合。每次你需要选择两个属于不同集合的整数,如果这两个整数拥有大于等于p的公共质因数,那么把它们所在的集合合并。重复如上操作,直到没有可以合并的集合为止。现在Caima想知道,最后有多少个集合。输入输出......
  • C#集合和数据结构,随笔记录
    C#集合和数据结构System.Collections命名空间包含接口和类,这些接口和类定义各种对象(如列表/链表、位数组、哈希表、队列和堆栈)的集合            System.Collections.Generic命名空间:所有集合都直接或间接基于ICollection接口列表类集合类型:集合类型基......
  • tarjan模板
    因ppt太水遂有此文有向图求强连通分量点击查看代码voidtarjan(intx){ dfn[x]=low[x]=++num; stk.push(x); f[x]=1; for(inti=head[x];i;i=net[i]) { if(!dfn[to[i]]) { tarjan(to[i]); low[x]=min(low[x],low[to[i]]); } elseif(f[to[i]]) { l......
  • tarjan
    缩点有向图缩点(把一个强连通分量看成一个点),用于优化。树枝边:DFS时经过的边,即DFS搜索树上的边反祖边:也叫回边或后向边,与DFS方向相反,从某个结点指向其某个祖先的边横叉边:从某个结点指向搜索树中另一子树中的某结点的边,它主要是在搜索的时候遇到了一个已经访问过的结点,但......
  • 08-集合
    集合数组就是一个集合,集合实质上就是一个容器,可以容纳其他类型的数据;JDBC编程中通过select关键字查询出来的结果就是放在ResultSet集合当中,将集合传到前端然后遍历集合,将数据都展现出来。集合不能直接存储基本数据类型,集合也不能直接存储java对象;集合中存储的是引用注意:集合在J......
  • java中的集合(List、Set、Map集合使用大解析)
    一、java集合简介1.集合简介java集合可分为Set、List、Queue和Map四种体系。Java集合就像一种容器,可以把多个对象(实际上是对象的引用,但习惯上都称对象)“丢进”该容器中。从Java5增加了泛型以后,Java集合可以记住容器中对象的数据类型,使得编码更加简洁、健壮。2.集合和......
  • 深度学习服务器版本查看指令集合(显卡,Ubuntu,CUDA,gcc,conda,torch)
    1.查看显卡版本nvidia-smi-a|grepNVIDIA2.查看Ubuntu版本cat/proc/versionuname-a3.查看CUDA版本nvcc-V4.查看gcc版本gcc-v5.查看conda版本conda-V6.查看torch版本print(torch.__version__) #torch版本torch.version.cuda #torch对......
  • Tarjan算法求SCC,缩点
    Tanjan算法可以在O(n+m)的时间内求出强连通分量,常数小,是个非常优秀的算法。算法实现过程:dfn[x]表示x的dfs生成树上的编号,代表着时间戳,low[x]表示从x结点出发,能够访问到最早的时间戳。<1>进入u时,盖上时间戳,结点入栈。<2>枚举该点的结点的时候,分为三种情况:(1)如果该点v没有访......
  • ELK日志实时分析平台搭建和使用 ELK日志分析平台是指Elasticsearch、Logstash 和 Kiba
    ELK日志实时分析平台搭建和使用ELK日志分析平台是指Elasticsearch、Logstash和Kibana三个项目的集合,后面又增加了Filebeat数据采集器。概述ELK日志分析平台是指Elasticsearch、Logstash和Kibana三个项目的集合,后面又增加了Filebeat数据采集器。Elasticsearch是一个数据......
  • Java集合面试高频问题---集合框架体系(3)
    HashMap源码分析HashMap常见属性扩容默认为数组容量加载印子即160.75put方法put添加数据流程图每次添加数据之后都判断是否需要扩容......