题意:K头牛分布在N个草场上,要聚在一起。草场与草场之间是有向边,问共有几个草场可作为K头牛聚集的地方。
解法:以每个草场为起点,用SPFA算法求出所有草场到它距离,如果所有有牛的草场可达此草场,则此草场可作为聚集的地点;枚举每个草场,求出数量即可。SPFA的期望复杂度是O(E),所以总复杂度是O(E*V)。
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
struct node
{
int u,v,w;
int next;
} nodes[100100];
int len=0;
int head[1001];
void addedge(int u,int v,int w)
{
nodes[len].u=u;
nodes[len].v=v;
nodes[len].w=w;
nodes[len].next=head[u];
head[u]=len++;
}
int que[10000];
int K,N,M;
bool rem[1001];
int dist[1001];
void spfa(int p)
{
for(int i=1;i<=N;i++)
dist[i]=N+1;
dist[p]=0;
que[0]=p;
int left=0,right=1;
while(left<right)
{
int tool=que[left];
for(int i=head[tool];i!=-1;i=nodes[i].next)
{
int a=nodes[i].v;
if(dist[a]>dist[tool]+nodes[i].w)
{
que[right++]=a;
dist[a]=dist[tool]+nodes[i].w;
}
}
left++;
}
}
int main()
{
scanf("%d%d%d",&K,&N,&M);
memset(head,-1,sizeof head);
for(int i=0;i<K;i++)
{
int a;
scanf("%d",&a);
rem[a]=true;
}
for(int i=0;i<M;i++)
{
int u,v;
scanf("%d%d",&u,&v);
addedge(v,u,1);
}
int ans=0;
for(int i=1;i<=N;i++)
{
spfa(i);bool flag=true;
for(int i=1;i<=N;i++)
{
if(rem[i]&&dist[i]>=N)
flag=false;
}
if(flag)ans++;
}
cout<<ans<<endl;
return 0;
}