首页 > 其他分享 >tarjan缩点(受欢迎的牛)

tarjan缩点(受欢迎的牛)

时间:2023-03-26 15:14:46浏览次数:36  
标签:缩点 tarjan int cnt low poi 受欢迎 now

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>

using namespace std;

int cnt;//计数 
int num;//时间戳 
int p;//栈的长度 
int last[200005];//上一条边的cnt 
int h[200005];//这一条边的cnt
int next_[200005];//这个点连的v2 
int dfn[200005];//该点是第几个被访问到的
int low[200005];//表示按照方向进行访问,能够访问到的最早的节点的时间戳
int stack[200005];//tarjan的栈 
bool op[200005];//判断是否进栈 
int n,m,a,b,ans;
int poi_num;//缩点的编号(个数) 
int poi_sum[50004];//第i个缩点所含的元素个数
int poi_id[50004];//第i个点所在的缩点编号 
int out_degree[50004];//出度 

inline void add( int  v1, int v2 ) {
	++ cnt;
	last[cnt] = h[v1];//v1所连的上一条边的cnt 
	h[v1] = cnt;//v1 v2边的cnt
	next_[cnt] = v2;//v1所连接的点(v2)
	return; 
}

void tarjan ( int now ) {
	dfn[now] = low[now] = ++ num;
	stack[++ p] = now;//进栈 
	op[now] = true;
	int point_cnt = h[now];//now的第一条边的cnt
	for (register int i = point_cnt; i != 0; i = last[i]) {
		if ( dfn[next_[i]] == 0 ) {//没查到过这个节点 
			tarjan( next_[i] );
			low[now] = min( low[now] , low[next_[i]] );
		}
		else {
			low[now] = min( low[now] , dfn[next_[i]] );
		}
	}
	if ( low[now] == dfn[now] ) {
		poi_num ++;//缩点编号(个数)+1 
		int temp;
		do {
			temp = stack[p];
			poi_sum[poi_num] ++;//第poi_num个缩点的元素个数加一 
			poi_id[temp] = poi_num;//第temp个点所在的缩点编号 
			op[temp] = false;
			p --;//弹出栈顶元素 
		} while ( now != temp );
	}
}

int main() {
	scanf("%d%d",&n,&m);
	for (register int i = 1; i <= m; ++i) {
		scanf("%d%d",&a,&b);
		add( a , b );
	}
	for (register int i = 1; i <= n; ++i) {
		if( dfn[i] == 0 ){
			tarjan( i );
		}
	} 
	for (register int i = 1; i <= n; ++i) {
		for (register int j = h[i]; j !=0; j = last[j]) {
			if ( poi_id[i] != poi_id[next_[j]] ) { //i与next[j]不在同一个缩点 
				out_degree[poi_id[i]] ++;//编号为poi_id[i]的缩点出度数+1 
			}
		}
	}
	for (register int i = 1; i <= poi_num; ++i) { //枚举每个缩点 
		if ( out_degree[i] == 0 ) { //编号为i的缩点的出度为0 
			if ( ans == 0 ) { //目前只有第i个缩点出度为0
				ans = poi_sum[i];
			}
			else { //目前有一个以上的缩点出度为0 
				ans = 0;
				break;
			}
			//如果出度为0的缩点个数为1,那么缩点的元素个数即为答案
			//如果出度为0的缩点个数大于1,那么答案为0
			//若出度为0的缩点个数为0,因为会形成一个更大的缩点,所以不可能 
		}
	}
	printf("%d\n",ans);
	return 0;
}

标签:缩点,tarjan,int,cnt,low,poi,受欢迎,now
From: https://www.cnblogs.com/jueqingfeng/p/17258696.html

相关文章

  • tarjan割点(备用交换机)
    #include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>usingnamespacestd;intcnt,last[2022],head[2022],next[2022];int......
  • tarjan割边
    #include<iostream>#include<cstdio>#include<cmath>#include<algorithm>#include<cstring>usingnamespacestd;intcnt=1,l[100005],h[100005],nex[100005];i......
  • Tarjan算法详解
    Tarjan算法介绍Tarjan算法是用于在有向图中求强连通分量的算法这里给出强连通分量的定义:有向图中一个最大的图,使这个图中每个两点都能够互相到达。这个最大的图称为强连......
  • 从缩点到圆方树
    一些概念连通:无向图中的任意两点都可以互相到达。强连通:有向图中的任意两点都可以互相到达。连通分量:无向图的极大连通子图。强连通分量:有向图的极大强连通子图。DFS......
  • Tarjan算法详解
    Tarjan算法介绍TarjanTarjan算法是用于在有向图中求强连通分量的算法这里给出强连通分量的定义:有向图中一个最大的图,使这个图中每个两点都能够互相到达。这个最大的图称......
  • tarjan-xue-xi-bi-ji
    title:'tarjan学习笔记'date:2022-12-3015:00:56tags:[学习笔记]published:truehideInList:falsefeature:isTop:false1.概念强连通分量:在有向图或无向图......
  • 最受欢迎的大数据可视化
    大数据可视化​是进行各种大数据分析的最重要组成部分之一。一旦原始数据流被以图像形式表示时,以此做决策就变得容易多了。为了满足并超越客户的期望,大数据可视化工具......
  • 22个受欢迎的Python不同类型开源框架
    22个受欢迎的Python不同类型开源框架记录:一、PythonWeb框架Django:PythonWeb应用开发框架链接:https://www.djangoproject.com/Django应该是最出名的Python框架,GAE甚......
  • 微软最受欢迎的前 10 名开源代码库
    微软最受欢迎的前10名开源代码库原创2022-11-2817:52·傻大个黑科技早在2018年,微软就以75亿美元的价格收购了GitHub,在此之前,它就像许多其他科技公司一样,一直是该......
  • CF1463E. Plan of Lectures(拓扑排序+缩点)——Educational Codeforces Round 100 (Rate
    目录题意思路代码参考题意条件1:给定一颗树,每个结点必须在父节点之后出现条件2:给定k个特殊点对u,v,u的下一个结点必须是v现在要求出满足上述两个条件结点序列(每个结点有......