原题链接:https://www.acwing.com/problem/content/1564/
思路分析
由题可知,题目会给出一个用户编号x,以及层数L,而我们需要根据输入的用户之间互相的关注情况,来求出用户x 在不超过L的层数的前提下,有多少用户是关注x的。
但是对于题目的输入数据,如果按照这个存图方式:即第 i 位用户关注的用户 j
即 v[i].push_back(j),
容易发现,这样子并不容易搜索第 j 位用户被谁搜索了(且要搜索L层)
所以,我们可以反向建图 即 v[j].push_back(i)
所以,总的思路即:
反向建图,然后从目标x开始搜索,搜索L层,看能搜索到多少个
注意: 记录层数时,可以用一个判断数组,如果未出现过,就层数+1,否则不加
if (!st[v[a][j]])
{
st[v[a][j]] = 1;
q.push(v[a][j]);
dist[v[a][j]] = dist[a] + 1;//记录层数!!!!
}
代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
using namespace std;
int n, l;
vector<int> v[1005];
int st[1005]; int dist[1005];
int res; int cnt;
int solve(int x)
{
memset(dist, 0, sizeof dist);
memset(st, 0, sizeof st);
res = 0;
cnt = 0;
queue<int> q;
q.push(x);
st[x] = 1;
while (!q.empty())
{
int a = q.front();
q.pop();
int j = 0;
while (j < v[a].size())
{
if (!st[v[a][j]])
{
st[v[a][j]] = 1;
q.push(v[a][j]);
dist[v[a][j]] = dist[a] + 1;//记录层数!!!!
}
j++;
}
}
for (int i = 1; i <= n; i++)
{
if (dist[i] >= 1 && dist[i] <= l)
cnt++;
}
return cnt;
}
int main()
{
int k = 0;
cin >> n >> l;
for (int i = 1; i <= n; i++)
{
int x = 0; int xx = 0;
cin >> x;
for (int j = 1; j <= x; j++)
{
cin >> xx;
v[xx].push_back(i);//反向建图!!!
}
}
cin >> k;
while (k--)
{
int x = 0;
cin >> x;
cout << solve(x) << "\n";
}
return 0;
}