_HCl_ @ 2023-11-29 15:49:31
萌新刚学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;
}
by _HCl_ @ 2023-11-29 17:56:18
去重出问题了,此帖终结