关于tarjan求强连通分量(悬2关注)
  • 板块学术版
  • 楼主letianJOE
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/10/22 20:44
  • 上次更新2024/10/22 21:52:31
查看原帖
关于tarjan求强连通分量(悬2关注)
658497
letianJOE楼主2024/10/22 20:44

这是这道题的两个代码。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e4;
const int M=1e5;
int n,m;
int dfn[N+5],low[N+5],dfn_cnt;
int edge_cnt,to[M+5],nxt[M+5],head[M+5];
bool in[N+5];
vector<int>ans[N+5];
int belong[N+5],ans_cnt;
stack<int>stk;
bool book[N+5];
void add(int u,int v)
{
	edge_cnt++;
	to[edge_cnt]=v;
	nxt[edge_cnt]=head[u];
	head[u]=edge_cnt;
}
int out_stack()
{
	int now=stk.top();
	stk.pop();
	belong[now]=ans_cnt;
//	cout << ":" << endl;
	in[now]=false;
	return now;
}
void tarjan(int u)
{
	stk.push(u);
//	cout << head[u] << endl;
	in[u]=true;
	dfn[u]=low[u]=++dfn_cnt;
	for(int i=head[u];i;i=nxt[i])
	{
		int v=to[i];
		if(dfn[v]==0)
		{
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(in[v]==true) 
			low[u]=min(low[u],dfn[v]); //这一行
	}
	if(dfn[u]==low[u])
	{
		ans_cnt++;
		while(stk.top()!=u)
			ans[ans_cnt].push_back(out_stack());
		ans[ans_cnt].push_back(out_stack());
	}
	return ;
}
main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int u,v;
		cin>>u>>v;
		add(u,v);
	}
	for(int i=1;i<=n;i++)
		if(dfn[i]==0)
			tarjan(i);
	cout<<ans_cnt<<"\n";
	for(int i=1;i<=n;i++)
		sort(ans[i].begin(),ans[i].end());
	for(int i=1;i<=n;i++)
	{
		if(book[belong[i]])
			continue;
		book[belong[i]]=true;
		for(int j=0;j<ans[belong[i]].size();j++)
			cout<<ans[belong[i]][j]<<" ";
		puts(""); 
	}
	return 0;
}
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e4;
const int M=1e5;
int n,m;
int dfn[N+5],low[N+5],dfn_cnt;
int edge_cnt,to[M+5],nxt[M+5],head[M+5];
bool in[N+5];
vector<int>ans[N+5];
int belong[N+5],ans_cnt;
stack<int>stk;
bool book[N+5];
void add(int u,int v)
{
	edge_cnt++;
	to[edge_cnt]=v;
	nxt[edge_cnt]=head[u];
	head[u]=edge_cnt;
}
int out_stack()
{
	int now=stk.top();
	stk.pop();
	belong[now]=ans_cnt;
//	cout << ":" << endl;
	in[now]=false;
	return now;
}
void tarjan(int u)
{
	stk.push(u);
//	cout << head[u] << endl;
	in[u]=true;
	dfn[u]=low[u]=++dfn_cnt;
	for(int i=head[u];i;i=nxt[i])
	{
		int v=to[i];
		if(dfn[v]==0)
		{
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(in[v]==true)
			low[u]=min(low[u],low[v]);
	}
	if(dfn[u]==low[u])
	{
		ans_cnt++;
		while(stk.top()!=u)
			ans[ans_cnt].push_back(out_stack());
		ans[ans_cnt].push_back(out_stack());
	}
	return ;
}
main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int u,v;
		cin>>u>>v;
		add(u,v);
	}
	for(int i=1;i<=n;i++)
		if(dfn[i]==0)
			tarjan(i);
	cout<<ans_cnt<<"\n";
	for(int i=1;i<=n;i++)
		sort(ans[i].begin(),ans[i].end());
	for(int i=1;i<=n;i++)
	{
		if(book[belong[i]])
			continue;
		book[belong[i]]=true;
		for(int j=0;j<ans[belong[i]].size();j++)
			cout<<ans[belong[i]][j]<<" ";
		puts(""); 
	}
	return 0;
}

想要问一下有什么区别。

如果可以的话,希望评论区的大佬们可以给我解答一下low的含义,有些地方搞不懂。

2024/10/22 20:44
加载中...