Tarjan例题:洛谷 P2863 [USACO06JAN] The Cow Prom S

发布时间 2023-08-10 18:14:21作者: 今添

在洛谷中查看

模板题,缩完点后扫一遍就行了。

巩固基础。


#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+5;
int n,m,dfn[N],low[N],val[N],new_val[N],num,cnt,col[N],st[N],top;
vector<int> g[N],new_g[N];
inline int read(){
	int s=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){s=(s<<1)+(s<<3)+(c^48);c=getchar();}
	return s*f;
}
void tarjan(int x){
	dfn[x]=low[x]=++num;st[++top]=x;
	for(int i=0;i<g[x].size();i++){
		int t=g[x][i];
		if(!dfn[t])tarjan(t),low[x]=min(low[x],low[t]);
		else if(!col[t])low[x]=min(low[x],dfn[t]);
	}
	if(dfn[x]==low[x])for(cnt++;st[top+1]!=x;top--)col[st[top]]=cnt,new_val[cnt]+=val[st[top]];
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++)val[i]=1;//可以都设为1,最后找new_val>1的 
	for(int i=1;i<=m;i++){
		int u=read(),v=read();
		g[u].push_back(v);
	} 
	for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
	int ans=0;
	for(int i=1;i<=cnt;i++)ans+=(new_val[i]>1);
	cout<<ans;
	return 0;
}