题目大意:
在微博中,每个用户都可能被若干其他用户关注。而当该用户发布一条消息时,关注他的人就可以看到这条信息并且选择是否转发它,且转发的消息也可以被关注他的人再次转发,但是同一用户最多转发该信息一次(信息的最初发布者不能转发该消息),现在给出N个用户的关注情况以及一个转发层数上限L,并给出最初发布消息的用户编号,求在转发层数上限内消息最多会被多少用户转发
算法思路:
首先得理解题意
assuming that only L levels of indirect followers are counted.
这里的$indirect$ $followers$指的是除了发布者以外的关注他的人,而不是在所有关注者中除了第一个关注者之外的人
calculate the maximum potential amount of forwards for any specific user
这句话指的是计算L层内的所有不同的人有多少个,$potential$ $ amount$就是可能转发的意思,其实就是以发布者为中心的L层内的总人数,对于人A有关注A的人B存在,那么A发布的微博B是可以看的到的,那么就存在一条微博传递路径$A->B$,对于输入中$user[i]$和$userlist[i]$实际上是$user[i]$关注了$userlist[i]$,所以有一条$userlist[i]->user[i]$的微博传递路径。
在理解题意后很清楚的知道我们要求的是在发布者为中心传播L层内的所有人数,很自然就联想到广度优先遍历的方法求解此题。为了方便的记录每一个节点的层数从而统计L层内的人数,我们建立结构体Node将人员的编号和层数进行绑定,然后在广度优先遍历的时候,每次出队的时候,只要出队节点的层数大于L,直接退出循环,否则就统计除了本人的转发人数。
注意点:
- 1、使用DFS最后一个测试点会超时。
- 2、每一个人只能转发一次,需要去重,可以使用$unordered$_$set$解决,这里使用了入队标记数组。
- 3、每次查询需要初始化$visited$
- 4、存储数组大小得开到1001以上否则最后一组测试点出现运行时错误。
提交结果:
AC代码:
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
struct Node{
int index;
int level;
};
int N,L;//总人数,层数
vector<int> G[1001];// 设置为1000会导致测试点4运行时错误
bool visited[1001];// 入队标记数组
void BFS(int start){
queue<Node> q;
q.push(Node{start,0});
int count = 0;// 统计L层内的人数
visited[start] = true;
while(!q.empty()){
Node top = q.front();
q.pop();
if(top.level>L){
break;
} else {
// 不统计自己
if(top.index!=start) ++count;
for(int i=0;i<G[top.index].size();++i){
int next = G[top.index][i];
if(!visited[next]){
visited[next] = true;
q.push(Node{next,top.level+1});
}
}
}
}
printf("%d\n",count);
}
int main()
{
scanf("%d %d",&N,&L);
int num,followed;
for (int i = 1; i <= N; ++i) {
scanf("%d",&num);
for (int j = 0; j < num; ++j) {
scanf("%d",&followed);
G[followed].push_back(i);
}
}
int K,user;
scanf("%d",&K);
// K个查询
for(int i=0;i<K;++i){
scanf("%d",&user);
memset(visited,0, sizeof(visited));
BFS(user);
}
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。