【1076】Forwards on Weibo (图BFS)

简介: 同一层可以有多个粉丝进行转发,所以显然用BFS合适。基础题。不过写的时候出现了是三个傻逼BUG,实在该打!(1)在输入点的坐标的for循环时候忘记结点的编号是1~N,而不

1.题目

https://pintia.cn/problem-sets/994805342720868352/problems/994805392092020736

微博转发背景,给出N个用户的关注情况(关注的人有哪些)和转发层数上限L,用最初发布消息的用户编号进行查询,求在转发层数上限内消息最多会转发的用户数。

2.思路

同一层可以有多个粉丝进行转发,所以显然用BFS合适。

基础题。不过写的时候出现了是三个傻逼BUG,实在该打!

(1)在输入点的坐标的for循环时候忘记结点的编号是1~N,而不是0,所以不能习惯地对for循环里面的i从0开始遍历;

(2)由于我一开始搞的crossnum是个全局变量,每次查询后不要忘记对其进行清零,或者就定义再BFS里面也行(然后搞个返回值额)就不需要清零了;

(3)注意逻辑要清晰,Node start=Node(i,0)一开始Node的第一个参数写成了a了,导致错误。

题目给出的是当前i结点的关注的人a,不要对下标写反了,应该是adj[a].push_back(start)。

另外

(1)为了减少代码行数,可以在结构体内使用构造函数,而初始化可以用Node start=Node(i,0)。

结构体内构造函数的三种方法。

(2)memset的头文件是<string.h>,而不是头文件< string>。

最好不用DFS:

(1)由于可能成环,因此必须控制每个用户只能转发消息一次(即遍历时只能访问一次);

(2)用DFS易出错,因有一种情况:一个用户X在第i次被访问,但此时已经达到转发层数上限(故无法继续遍历), 但用户可以通过另一条路径更快访问到(如下图:1到5有2条路径,转发上限为L=3,即有一条路径合法)。

DFS还可能导致同一个结点的转发次数被重复计算,需额外设置一个数组记录结点是否已经转发过消息。

image.png

3.完整代码

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
#include<queue>
#include<string.h>//memset的头文件
using namespace std;
const int N=1010;
int maxxx;//最大传播层数阈值
int crossnum=0;
//邻接表存储
struct Node{
  int v;
  int layer;
  Node(int a,int b):v(a),layer(b){ }//构造函数
  Node(int a){
    v=a;
  }
};
vector<Node>adj[N];
bool inq[N]={false};
int BFS(int index){
  queue<Node>q;
  Node start=Node(index,0);
  q.push(start);
  inq[start.v]=true;
  while(!q.empty()){
    Node topNode=q.front();
    q.pop();
    int u=topNode.v;
    for(int i=0;i<adj[u].size();i++){
      Node next=adj[u][i];
      next.layer=topNode.layer+1;
      if(inq[next.v]==false&& ((next.layer)<=maxxx)){
        q.push(next);
        inq[next.v]=true;
        crossnum++;
      }
    }
  }
  return crossnum;
}
int main(){
  int vnum;
  scanf("%d%d",&vnum,&maxxx);
  //输入阶段(存储图)
  for(int i=1;i<=vnum;i++){//注意结点编号从1开始,所以i非0开始
    int n1;
    scanf("%d",&n1);//i号用户关注的人数
    for(int j=0;j<n1;j++){
      int a;
      scanf("%d",&a);//i号用户关注的人的编号
      Node start=Node(i,0);//一开始Node的第一个参数写成了a了,导致错误
      adj[a].push_back(start);
    }
  }
  //最后一行(查询步骤)
  int qnum;
  scanf("%d",&qnum);
  for(int i=0;i<qnum;i++){
    memset(inq,false,sizeof(inq));
    crossnum=0;//每次输出之后需要清零
    int startnode;
    scanf("%d",&startnode);
    BFS(startnode);
    printf("%d\n",crossnum);
    //crossnum=0;//每次输出之后需要清零
  }
  system("pause");
}

相关文章
|
6月前
|
存储 算法 Java
广度优先搜索(Breadth-First Search,BFS)是一种用于图的遍历或搜索的算法。
广度优先搜索(Breadth-First Search,BFS)是一种用于图的遍历或搜索的算法。
|
6月前
|
算法 Python
蓝桥杯-搜索BFS+DFS
蓝桥杯-搜索BFS+DFS
41 2
|
存储 算法
深度优先遍历(DFS):探索图的奥秘
当进行深度优先遍历(DFS)时,我们需要按照一定的步骤来遍历图中的节点。 选择起始节点:选择图中的一个起始节点作为遍历的起点。 标记已访问:将起始节点标记为已访问,并将其放入数据结构中,比如栈或递归调用。 探索相邻节点:从起始节点开始,探索与其相邻的节点。这是通过查找邻接表来实现的,邻接表存储了每个节点的相邻节点信息。 深入探索:选择一个相邻节点,标记为已访问,并将其放入数据结构中。然后,从这个相邻节点出发,继续探索其相邻节点,形成一个深入的路径。这一步是递归的核心。 回溯:当没有未访问的相邻节点时,回溯到上一个节点,继续探索其他未访问的相邻节点。这可以通过从数据结构中弹出节点来实现,或者从递
305 0
|
算法 Python
基于python实现深度优先遍历搜索(DFS)
基于python实现深度优先遍历搜索(DFS)
514 0
基于python实现深度优先遍历搜索(DFS)
es 实现图的基本算法 图的深度优先搜索 广度优先搜索 普利姆算法
es 实现图的基本算法 图的深度优先搜索 广度优先搜索 普利姆算法
es 实现图的基本算法 图的深度优先搜索 广度优先搜索 普利姆算法
|
算法 Java
java实现图的深度优先搜索(DFS)和广度优先搜索(BFS)
深度优先搜索、宽度优先搜索算法属于图算法的一种。
684 0
java实现图的深度优先搜索(DFS)和广度优先搜索(BFS)
|
存储
【每日一题Day61】寻找图中是否存在路径 | BFS 并查集
初始时将source设为已访问,并且将其加入队列。之后每次将队列中的节点出队,并将其能够到达的未访问过的节点入队。如果访问到destination,则直接返回true;如果队列为空,仍未访问到destination,则返回false
117 0
看“图”有惊喜哦(图基本介绍 DFS BFS)
1.图基本介绍 1.图的常用概念 2.图的表示方式 1.邻接矩阵 2.邻接表 3.快速入门案例 2.图遍历 1.深度优先遍历 2.广度优先遍历
看“图”有惊喜哦(图基本介绍 DFS BFS)
|
存储 C++
C++实现图 - 02 图的遍历(DFS、BFS)
上一讲我们对图有了一个大概的了解,但是只讲了如何存储图,还没有讲如何遍历图。这一讲我们来介绍图的遍历方式,一共分为深度优先搜索(DFS)和宽度优先搜索(BFS)。
540 0
C++实现图 - 02 图的遍历(DFS、BFS)