1. 程式人生 > 其它 >【1076】Forwards on Weibo (圖BFS)

【1076】Forwards on Weibo (圖BFS)

技術標籤:BFS和DFS

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還可能導致同一個結點的轉發次數被重複計算,需額外設定一個數組記錄結點是否已經轉發過訊息。
在這裡插入圖片描述

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"); }