WA 40 蒟蒻求调
查看原帖
WA 40 蒟蒻求调
542879
_HCl_楼主2023/11/29 15:49

萌新刚学OI,可能会有一些奇妙错误,大佬见谅。

做法是tarjan缩点+记忆化搜索,参考第3篇题解。

#include<bits/stdc++.h>
using namespace std;
int n,m,MOD;
vector<int> e[100001],g[100001];
int dfn[100001],low[100001],vis[100001],col[100001],ccf[100001],num,tlog;
stack<int> s;
void tarjan(int x){
	low[x]=dfn[x]=++tlog;
	s.push(x);
	vis[x]=1;
	for(int i=0;i<e[x].size();++i){
		int y=e[x][i];
		if(!dfn[y]){
			tarjan(y);
			low[x]=min(low[x],low[y]); 
		}
		else if(vis[y])low[x]=min(low[x],dfn[y]);
	}
	if(low[x]==dfn[x]){
		num++;
		while(s.top()!=x){
			int u=s.top();
			s.pop();
			col[u]=num;
			ccf[num]++;
			vis[u]=0;
		}
		s.pop();
		col[x]=num;
		ccf[num]++;
		vis[x]=0;
	}
}
int ans1=-1,ans2;
int ind[100001],otd[100001],f[100001],d[1000001],a[1000001];
void dfs(int x){
	f[x]=1;
	if(!otd[x]){
		d[x]=ccf[x],a[x]=1;
		ans1=max(ans1,d[x]);
		return;
	}
	for(int i=0;i<g[x].size();++i){
		int y=g[x][i];
		if(!f[y])dfs(y);
		if(d[y]+ccf[x]>d[x]){
			d[x]=d[y]+ccf[x];
			a[x]=a[y]%MOD;
		}
		else if(d[x]==d[y]+ccf[x]){
			a[x]=(a[x]+a[y])%MOD;
		}
		ans1=max(ans1,d[x]);
	}
}
int main(){
	cin>>n>>m>>MOD;
	for(int i=1;i<=m;++i){
		int u,v;
		scanf("%d%d",&u,&v);
		e[u].push_back(v);
	} 
	for(int i=1;i<=n;++i){
		if(!dfn[i])tarjan(i);
	}
	for(int i=1;i<=n;++i){
		for(int j=0;j<e[i].size();++j){
			int y=e[i][j];
			if(col[i]!=col[y])g[col[i]].push_back(col[y]),ind[col[y]]++,otd[col[i]]++;
		}
	}
	for(int i=1;i<=num;++i){
		sort(g[i].begin(),g[i].end());
		unique(g[i].begin(),g[i].end());
	}
	for(int i=1;i<=num;++i)if(!f[i]&&!ind[i])dfs(i);
	for(int i=1;i<=num;++i)if(d[i]==ans1)ans2=(ans2+a[i])%MOD;
	cout<<ans1<<"\n"<<ans2;
}
2023/11/29 15:49
加载中...