Tarjan板子挂了求条

rt,Tarjan板子挂了求条。

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
int n,m,cnt,top,ans;
int dfn[N],low[N],stk[N],rt[N],vis[N];
vector<int>v[N],point[N];
void Tarjan(int x)
{
	dfn[x]=low[x]=++cnt;
	stk[++top]=x;
	for(auto i:v[x])
	{
		if(!dfn[i])
		{
			Tarjan(i);
			low[x]=min(low[x],low[i]);
		}
		else if(!rt[i]) low[x]=min(low[x],dfn[i]);
	}
	if(dfn[x]==low[x])
	{
		ans++;
		rt[x]=x;
		point[x].push_back(x);
		while(stk[top]!=x)
		{
			rt[stk[top]]=x;
			point[x].push_back(stk[top]);
			top--;
		}
		top--;
	}
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;++i)
	{
		int x,y;
		cin>>x>>y;
		v[x].push_back(y);
	}
	for(int i=1;i<=n;++i)
	if(!dfn[i]) Tarjan(i);
	cout<<ans<<endl;
	for(int i=1;i<=n;++i)
	if(!vis[i])
	{
		sort(point[i].begin(),point[i].end());
		for(auto j:point[i])
		{
			vis[j]=1;
			cout<<j<<" ";
		}
		if(!point[i].empty()) cout<<endl;
	}
	return 0;
}
1 个赞

我对照我的板子tarjan写的好像没问题啊,但缩点我的写法是tarjan跑完后再缩的

1 个赞

这个不是自环吗?

1 个赞

对了忘记放题了
https://www.luogu.com.cn/problem/B3609

这个是指x在自己的强联通里

好奇妙啊,你对照下我的板子吧,刚刚把这题A了

#include<bits/stdc++.h>
#define IV vector<int>::iterator
const int N=114514;
using namespace std;
int cnt,dfn_cnt,sc_cnt,new_cnt;
int head[N],low[N],dfn[N],inst[N];
int nhead[N],nw[N];///记录每个强连通分量在新图的编号(new_cnt)
int sc[N],p[N],in[N],dp[N];
int vis[N];
int n,m,nn;
stack<int> st;
vector<int> scc[N]; 
struct edge{
	int to,next;
}e[N];
void add_edge(int u,int v){
	e[++cnt].to=v;	
	e[cnt].next=head[u];
	head[u]=cnt; 
} 
void tarjan(int u){
	dfn[u]=low[u]=++dfn_cnt;
	st.push(u);inst[u]=true;
	for(int i=head[u];i;i=e[i].next){
			int v=e[i].to;
			if(!dfn[v]){//没有遍历过 
				tarjan(v);//跑一边tarjan 
				low[u]=min(low[u],low[v]);
			}
			else if(inst[v]){//已经遍历过但没有处理 
				low[u]=min(low[u],dfn[v]);
			}
	}
	if(low[u]==dfn[u]){
		sc[u]=++sc_cnt;
		scc[sc_cnt].push_back(u);
		inst[u]=false;
		while(st.top()!=u){
			inst[st.top()]=false;
			sc[st.top()]=sc_cnt;
			scc[sc_cnt].push_back(st.top());			
			st.pop();
			
		}			
		st.pop();
	}
}

int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>a[i].u>>a[i].v;
		add_edge(a[i].u,a[i].v);
	} 
	for(int i=1;i<=n;i++){
		if(!dfn[i]) tarjan(i);
	}
    cout<<sc_cnt<<endl;
	for(int i=1;i<=n;i++) {
		if(!vis[sc[i]]){
			vis[sc[i]]=1;
			sort(scc[sc[i]].begin(),scc[sc[i]].end());
			for(auto j:scc[sc[i]]){
				cout<<j<<" ";
			}
			cout<<endl;
		}
	}
    //system("pause");
	return 0;
}
/*



out 6911
*/

感觉没问题呀

1 个赞

恭喜金杭东大佬成为学生管理员!

1 个赞

恭喜恭喜

1 个赞