### 反向建边+dfs
用f记录一个牧场是否有cow,如果没有cow,则不用管这个牧场,然后枚举每个点作为cow野餐的地方,dfs,用vis记录一个牧场能不能被访问到,然后for一遍判断该牧场是否有cow,和该牧场能不能被枚举的点走到,就做完了。
### 注意,每次dfs时,vis数组要清空,我第一次交忘记清空,结果就WA了,30分
$Code :$
#include<iostream> #include<cstring> #include<cstdio> using namespace std; inline int read(){ register int x=0,v=1,ch=getchar(); while(!isdigit(ch)){if(ch=='-')v=-1;ch=getchar();} while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^'0');ch=getchar();} return x*v; } const int MAX=1005,N=10005; int k,n,m; struct Edge{ int e,next; }e[N]; int head[MAX],cnt; inline void add(int u,int v){ e[cnt].e=v; e[cnt].next=head[u]; head[u]=cnt++; } int u,v,Ans=0;bool f[MAX],vis[MAX]; void dfs(int now){ vis[now]=1; for(register int i=head[now];i;i=e[i].next){ if(!vis[e[i].e])dfs(e[i].e); } } int main(){ k=read(),n=read(),m=read(); for(register int i=1;i<=k;++i){ f[read()]=1; } for(register int i=1;i<=m;++i){ u=read(),v=read(); add(v,u); } for(register int i=1;i<=n;++i){ memset(vis,0,sizeof(vis)); dfs(i); for(register int j=1;j<=n;++j){ if(vis[j]!=1&&f[j]==1){ goto end; } } ++Ans; end:; } printf("%d\n",Ans); return 0; }