思路
记忆化搜索、拓扑排序的题目。
对于一个已经走过一次的点,后面能走的情况都是确定的,
只要能把情况数记录下来,后面的结点就不需要再走一遍了,
就可以很大程度上节省时间。
代码
#include <bits/stdc++.h>
using namespace std;
const int maxm=200005,maxn=100005;
struct E{
int next, to;
}edge[maxm];
int head[maxn], cnt, ans;
int n,m,a,b,ru[maxn],chu[maxn],f[maxn];
void addedge(int a,int b){
edge[++cnt].next=head[a];
edge[cnt].to=b;
head[a]=cnt;
}
int dfs(int now){
if(f[now]) return f[now]; //记忆化
if(!chu[now]) return 1;
int res=0;
for(int i=head[now];i;i=edge[i].next){
res+=dfs(edge[i].to);
}
f[now]=res;
return res;
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);
cin>>n>>m;
memset(ru, 0, sizeof(ru));
memset(chu, 0, sizeof(chu));
for(int i=1;i<=m;i++){
cin>>a>>b;
addedge(a,b);
ru[b]++,chu[a]++;
}
for(int i=1;i<=n;i++){
if(!ru[i]&&chu[i]) ans+=dfs(i);
}
cout<<ans;
return 0;
}

京公网安备 11010502036488号