强连通分量————Tarjan模板

原题链接:牛客网学术认可
Tarjan算法学习视频:b站
自作代码:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 50005;
const int maxm = 600005;
int n,m,x,y,ans = 0,cnt,tmp;
struct Edge
{
	int to,next;
}e[maxm];
int head[maxm],tot=0;
void add(int &u,int &v)
{
	e[++tot].to = v;
	e[tot].next = head[u];
	head[u] = tot;
}

int Time = 1;
int dfn[maxn]{0},low[maxn]{0},in_stack[maxn]{0};
int stack[maxn]{0},s = 0;
void Tarjan(int id)
{
	stack[s++] = id;
	in_stack[id] = 1;
	dfn[id] = low[id] = Time++;
	for(int i = head[id];i!=-1;i=e[i].next)
	{
		if(!dfn[e[i].to])
		{
			Tarjan(e[i].to);
			low[id] = min(low[id],low[e[i].to]);
		}
		else if(in_stack[e[i].to])
			low[id] = min(low[id],low[e[i].to]); 

	}
	if(dfn[id] == low[id])
	{
		cnt = 0;
		do
		{
			tmp = stack[--s];
			in_stack[tmp] = 0;
			cnt++;
		}while(tmp!=id);
		ans += cnt *(cnt - 1) / 2;
	}	
}


int main()
{
	cin>>n>>m;	
	memset(head,-1,sizeof(head));
	for(int i = 0 ;i < m ; i ++ )
	{
		cin>>x>>y;
		add(x,y);
	}

	for(int i = 1; i <= n; i++)
		if(!dfn[i])
			Tarjan(i);
	cout<<ans;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值