【蓝桥杯集训·每日一题】AcWing 1562. 微博转发

文章目录

  • 一、题目
    • 1、原题链接
    • 2、题目描述
  • 二、解题报告
    • 1、思路分析
    • 2、时间复杂度
    • 3、代码详解
  • 三、知识风暴
  • 宽搜BFS

一、题目

1、原题链接

1562. 微博转发

2、题目描述

微博被称为中文版的 Twitter。

微博上的用户既可能有很多关注者,也可能关注很多其他用户。

因此,形成了一种基于这些关注关系的社交网络。

当用户在微博上发布帖子时,他/她的所有关注者都可以查看并转发他/她的帖子,然后这些人的关注者可以对内容再次转发…

现在给定一个社交网络,假设只考虑 L 层关注者,请你计算某些用户的帖子的最大可能转发量

补充 如果 B 是 A 的关注者,C 是 B 的关注者,那么 A 的第一层关注者是 B,第二层关注者是 C。

输入格式

第一行包含两个整数,N 表示用户数量,L 表示需要考虑的关注者的层数。

假设,所有的用户的编号为 1∼N。

接下来 N 行,每行包含一个用户的关注信息,格式如下:

M[i] user_list[i] M[i] 是第 i 名用户关注的总人数,user_list[i] 是第 i 名用户关注的 M[i] 个用户的编号列表。

最后一行首先包含一个整数 K,表示询问次数,然后包含 K 个用户编号,表示询问这些人的帖子的最大可能转发量。

输出格式

按顺序,每行输出一个被询问人的帖子最大可能转发量。

假设每名用户初次看到帖子时,都会转发帖子,只考虑 L 层关注者。

数据范围

1≤N≤1000,1≤L≤6,1≤M[i]≤100,1≤K≤N

输入样例

7 3
3 2 3 4
0
2 5 6
2 3 1
2 3 4
1 4
1 5
2 2 6

输出样例

4
5

二、解题报告

1、思路分析

思路来源:y总讲解视频
y总yyds

(1)可以将本题关系存储在图中,将每个人和他的粉丝之间连一条有向边,由被关注者指向粉丝。
(2)该问题就变成了从每个人开始,经过的边数不超过l可以到达的点数,即为答案。
(3)可以利用宽搜来实现,从询问的人开始搜索l层,统计可以到达的点数即为答案。

2、时间复杂度

时间复杂度为O(k(n+m))(k为询问数,n为点数,m为边数,宽搜时间复杂度为O(n+m))

3、代码详解

#include 
#include 
#include 
using namespace std;
const int N=1010,M=100010;    //N代表点数,M代表边数
int n,l,k;
int h[N],e[M],ne[M],idx;  //h[]存储每个点的第一条边的编号,e[]存储每条边终点的值,ne[]存储每条边同起点的下一条边的编号,idx为边的编号
bool st[N];          //st[]存储每个点是否已经遍历过
//添加一条边a->b
void add(int a,int b){
    e[idx]=b;
    ne[idx]=h[a];
    h[a]=idx++;
}
int bfs(int id){
    int ans=0;
    queue<int> q;
    memset(st,0,sizeof st);
    q.push(id);
    st[id]=true;
    //循环l层,统计ans
    for(int i=0;i<l;i++){
        int cnt=q.size();    //记录该层的点数
        while(cnt--){        //依次遍历该层的每个点,将每个点可以到达且没有遍历过的点加入队列
            int t=q.front();
            q.pop();
            //遍历每个点可以到达的点
            for(int i=h[t];i!=-1;i=ne[i]){
                int j=e[i];
                if(!st[j]){
                    st[j]=true;
                    q.push(j);
                    ans++;
                }
            }
        }
    }
    return ans;
}
int main(){
    cin>>n>>l;
    memset(h,-1,sizeof h);
    for(int i=1;i<=n;i++){
        int num,id;
        cin>>num;
        for(int j=0;j<num;j++){
            cin>>id;
            add(id,i);         //添加一条边,由被关注者指向粉丝
        }
    }
    cin>>k;
    while(k--){
        int m;
        cin>>m;
        cout<<bfs(m)<<endl;
    }
    return 0;
}

三、知识风暴

宽搜BFS

  • 尽可能向横向搜索,具有“最短性”(边权都为1时可以用BFS求最短路)。

你可能感兴趣的:(蓝桥杯集训·每日一题+周赛,蓝桥杯,算法,职场和发展,c++,数据结构)