思路
一个牧场如果能被所有牛都访问到,就可以贡献一个答案。
最初想法是从每个有牛的牧场开始dfs,碰到有牛的牧场就“带上这只牛”,并把该牧场变成没有牛的牧场。但是这样做不好处理有环的情况,因为很难维护两次访问起点之间“带上了多少牛”。
退而求其次,碰到一只陌生的牛不带它,只将能够到达的牧场的访问次数加1,最后统计有多少牧场的访问次数为K。虽然比上一个算法慢一些,但是代码很好写。
代码
#include <bits/stdc++.h>
#define rep(i,st,ed) for(int i=st;i<=ed;++i)
const int K=103,N=1E3+10,M=1E4+10;
using namespace std;
int k,n,m,tot,ans;
int vis[N],head[N],have[N],a[N];
struct Edge
{
int nxt,to;
}e[M];
void add_edge(int u,int v)
{
e[++tot].nxt=head[u];e[tot].to=v;head[u]=tot;
}
void dfs(int u)
{
vis[u]=1;
++a[u];
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(vis[v])
continue;
dfs(v);
}
}
int main()
{
scanf("%d%d%d",&k,&n,&m);
rep(i,1,k)
{
scanf("%d",have+i);
}
int u,v;
rep(i,1,m)
{
scanf("%d%d",&u,&v);
add_edge(u,v);
}
rep(i,1,k)
{
memset(vis,0,sizeof(vis));
dfs(have[i]);
}
rep(i,1,n)
{
if(a[i]==k)
++ans;
}
cout<<ans<<endl;
}