题目大意:
一个用户发布一条信息,他的关注这就可以看到这条信息并且选择是否转发,同一用户最多转发一次,信息发布者不会转发
给出n个用户的关注情况,以及他们关注了那些用户,以及一个转发上限L,应给出最初发布消息的用户编号,查询在转发层数内消息有多少会被转发
思路:
建立图,X关注了Y,建立Y->X的有向边,表示Y发布的消息可以传到X并被X转发。
如样例输入中第二行 3234代表节点1关注了2,3,4即2,3,4发微博1可以转发,即234的邻接表项中加入1。
使用BFS带层次节点遍历,控制遍历的层次在给定的层次之内
这种需要控制层数的尽量用bfs,dfs容易超时。
AC代码
//PAT_A 1076
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 1010;
struct Node {
int id;
int layer;
};
vector<Node> Adj[maxn];//邻接表
bool inq[maxn] = { false };
int bfs(int s, int L) {
int numForward = 0;//转发数
queue<Node> q;
Node start{ s,0 };
q.push(start);
inq[start.id] = true;
while (!q.empty()) {
Node topNode = q.front();
q.pop();
int u = topNode.id;
for (int i = 0; i < Adj[u].size(); i++) {
Node next = Adj[u][i];
next.layer = topNode.layer + 1;
if (inq[next.id] == false && next.layer <= L){
q.push(next);
inq[next.id] = true;
numForward++;
}
}
}
return numForward;
}
int main() {
Node user;
int n, L, numFollow, idFollow;
(void)scanf("%d %d", &n, &L);
for (int i = 1; i <= n; i++) {
user.id = i;
(void)scanf("%d", &numFollow);
for (int k = 0; k < numFollow; k++) {//建立idFollow->user的边
(void)scanf("%d", &idFollow);
Adj[idFollow].push_back(user);
}
}
int numQuery, s;
(void)scanf("%d", &numQuery);
for (int i = 0; i < numQuery; i++) {
fill(inq, inq + maxn, false);
(void)scanf("%d", &s);
int numForward = bfs(s, L);
printf("%d\n", numForward);
}
return 0;
}