建反图,跑一个拓扑排序dp即可.
Code:
#include <bits/stdc++.h> #define ll long long #define N 100005 #define setIO(s) freopen(s".in","r",stdin) using namespace std; ll f[N]; queue<int>q; int edges,n,m; int in[N],out[N],hd[N],to[N<<1],nex[N<<1],mk[N]; void add(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } int main() { int i,j; // setIO("input"); scanf("%d%d",&n,&m); for(i=1;i<=m;++i) { int a,b; scanf("%d%d",&a,&b),add(b,a),++in[a],++out[b]; } for(i=1;i<=n;++i) { if(in[i]==0 && out[i]!=0) { q.push(i),f[i]=1,mk[i]=1; } } for(;!q.empty();) { int u=q.front();q.pop(); for(int i=hd[u];i;i=nex[i]) { int v=to[i]; f[v]+=f[u]; --in[v]; if(in[v]==0) q.push(v); } } ll ans=0; for(i=1;i<=n;++i) { if(out[i]==0 && !mk[i]) { ans+=f[i]; } } printf("%lld ",ans); return 0; }