(悬·关)tarjan求调64pts(简单题)
查看原帖
(悬·关)tarjan求调64pts(简单题)
756805
xuweiyi楼主2024/8/23 21:47

萌新刚学oi,感谢dalao。

#include<bits/stdc++.h>
using namespace std;
#define fr(fgh,asd,i) for(int i=fgh,i##end=asd;i<=i##end;++i)
#define rf(fgh,asd,i) for(int i=fgh,i##end=asd;i>=i##end;--i)
typedef long long ll;
#define max_(loo,rr) (loo>rr?loo:rr)
#define min_(loo,rr) (loo<rr?loo:rr)
#define maxn 10007
#define maxm 100007
int n,m;int head[maxn],edge[maxm],nxt[maxm],cnt=1;
inline void adde(int x,int y){nxt[++cnt]=head[x];edge[head[x]=cnt]=y;return;}
int dfn[maxn],low[maxn],d_=0,vis[maxn],in_stack[maxn],bel[maxn];
int st[maxn],tp=0;vector<int>scc[maxn];int size_=0;
void tarjan(int u){
	low[u]=dfn[u]=++d_;st[++tp]=u;in_stack[u]=true;
	for(int i=head[u];i;i=nxt[i]){
		int to=edge[i];
		if(!dfn[to]){
			tarjan(to);
			low[u]=min_(low[u],low[to]);
		}else if(in_stack[i]){
			low[u]=min_(low[u],dfn[to]);
		}
	}if(low[u]==dfn[u]){size_++;
		int dingdian=0;
		do{
			//一个强连通分量的顶点
			dingdian=st[tp];tp--;
			scc[size_].push_back(dingdian);
			bel[dingdian]=size_;
			in_stack[dingdian]=false;
		}while(dingdian!=u);
	}return;
}int od[maxn];
void dfs(int u){
	int now=bel[u];
	for(int i=head[u];i;i=nxt[i]){
		int to=edge[i],b=bel[to];
		if(b!=now){
			od[now]=1;
		}
		if(!vis[to]) vis[to]=1,dfs(to);
	}
	return;
}
int main(){
	ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
	cin>>n>>m;
	fr(1,m,i){
		int A,B;cin>>A>>B;adde(A,B);
	}fr(1,n,i) if(!dfn[i]) tarjan(i);
	fr(1,n,i) if(!vis[i]) vis[i]=1,dfs(i);
	int ans=0,ct=0;
	fr(1,size_,i){
		if(od[i]==0){
			ans=scc[i].size();
			ct++;
		}
	}
	if(ct==1) printf("%d\n",ans);
	else printf("0\n");
	return 0;
}
2024/8/23 21:47
加载中...