#include<bits/stdc++.h>
using namespace std;
int bj[1000]={0},bl[1000]={0},ci[10000],c[10000],s[1000],k,m,n;
void dfs(int a)
{
bl[a]=1;
bj[a]++;
for(int i=0;i<m;i++)
if(a==c[i]-1&&bl[i]!=1)
dfs(ci[i]-1);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>k>>n>>m;
for(int i=0;i<k;i++)
cin>>s[i];
for(int i=0;i<m;i++)
cin>>c[i]>>ci[i];
for(int i=0;i<k;i++)
{
if(s[i]!=-1)
{
dfs(s[i]-1);
memset(bl, 0, sizeof(bl));
}
}
int ans=0;
for(int i=0;i<n;i++)
{
if(bj[i]==k)
ans++;
}cout<<ans;
return 0;
}
题解
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>//头文件准备
using namespace std;//使用标准名字空间
//以下为快速读入
inline int gi()
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar();}
return f * x;
}
int n, m, k, ans, g[1003][1003], c[1003], s[1003], vis[1003];
//n,m,k的含义如题面,ans为最终答案,g数组为邻接矩阵,c数组存储牛的位置,s数组为每个点被遍历的次数,vis数组用来判断点是否已经被访问过
void dfs(int x)//进行图的深度优先遍历
{
vis[x] = 1;//将现在访问的点标记为已遍历
++s[x];//将这个点遍历的次数+1
for (int i = 1; i <= n; i++)//枚举节点编号
{
if (!vis[i] && g[x][i]) //如果当前节点没有被访问过并且与当前节点有边连接
dfs(i);//就遍历i号节点
}
}
int main()
{
k = gi(), n = gi(), m = gi();//分别输入k,m,n(注意顺序)
for (int i = 1; i <= k; i++) c[i] = gi();//输入每只奶牛的顺序
for (int i = 1; i <= m; i++)
{
int u = gi(), v = gi(); //输入边两端的点的编号
g[u][v] = 1;//连接两边(注意不是双向边,是单向边)
}
for (int i = 1; i <= k; i++)//对奶牛的位置进行枚举
{
dfs(c[i]);//从每一只奶牛的位置开始遍历
memset(vis, 0, sizeof(vis));//记得每次遍历完都需要清空标记数组
}
for (int i = 1; i <= n; i++)
{
if (s[i] == k) ++ans;//统计答案,如果当前节点被访问的次数恰好为奶牛的只数
}
printf("%d\n", ans);//输出最后答案
return 0;//完美结束
}