PAT_甲级_1076 Forwards on Weibo (30point(s)) (C++)【BFS/微博扩散】

目录

1,题目描述

题目描述

输入

2,思路

BFS算法

3,AC代码

4,解题过程

第一搏

第二搏


1,题目描述

Sample Input:

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

 

Sample Output:

4
5

题目描述

一个人的微博可以被许多人转发,给出每个粉丝关注的人(形成联系网络),限定间接转发的次数,输出最大转发数。

输入

  1. 第一行:N总人数,L限制层数;
  2. N行:每个粉丝关注的人;(不要搞混了!!!)
  3. 最后一行:K查询的数目,查询的编号;

 

2,思路

典型的BFS算法,需要注意记录每个节点所在的层数。

BFS算法

  1. 声明队列q;设置初始阶段u已访问visited[u]=true;int [level]记录层数;bool visited[]判断节点是否已访问;
  2. 将初始节点u入队;
  3. 当队列不为空时:1)队列头结点出队,并记录为u;2)遍历所有与u相邻、未被访问且u节点层次小于L的节点v,将其入队设置已访问更新节点v层次;

 

3,AC代码

参考这位大神的代码,解题过程中有大帮助!膜!@日沉云起【pat甲级1076. Forwards on Weibo (30)——BFS+DFS】

#include<bits/stdc++.h>
using namespace std;
int N, L, K;                //N用户数目 L传递层数 K查询数目
vector<int> graph[1002];    //有向图 存放消息的传播路径

int bfs(int u){
    int amount = 0;         //传递的数量
    int level[N + 1] = {0}; //记录每个节点的层次
    bool visited[N + 1] = {false};
    queue<int> q;
    q.push(u);
    visited[u] = true;
    while(!q.empty()){
        u = q.front();
        q.pop();
        for(auto v : graph[u]){
            if(!visited[v] && level[u] < L){
                amount++;
                visited[v] = true;
                level[v] = level[u] + 1;    //节点v比节点u层数加一
                q.push(v);
            }
        }
    }
    return amount;
}
int main(){
#ifdef ONLINE_JUDGE
#else
    freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE

    scanf("%d %d", &N, &L);
    int num, id;
    for(int i = 1; i <= N; i++){        //编号从1开始
        scanf("%d", &num);
        for(int j = 0; j < num; j++){
            scanf("%d", &id);
            graph[id].push_back(i);     //信息可以从id流向i
        }
    }
    scanf("%d", &num);
    for(int i = 0; i < num; i++){
        scanf("%d", &id);
        printf("%d\n", bfs(id));
    }
    return 0;
}

 

4,解题过程

第一搏

一看,这不就是有向图的DFS遍历(因为用DFS的次数比较多,形成了定势思维)吗?看我分分钟KO。。。

#include<bits/stdc++.h>
using namespace std;
int N, L, K;//N用户数目 L传递层数 K查询数目
bool graph[1002][1002];//有向图 存放消息的传播路径
bool visited[1002];
int amount;//传递的数量

void dfs(int start, int depth){
    if(depth > L) return;
    visited[start] = true;
    amount++;
    for(int i = 1; i <= N && depth < L; i++){
        if(visited[i] == false && graph[start][i] == true)
            dfs(i, depth + 1);
    }
}
int main(){
#ifdef ONLINE_JUDGE
#else
    freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE

    scanf("%d %d", &N, &L);
    int num, id;
    for(int i = 1; i <= N; i++){//编号从1开始
        scanf("%d", &num);
        for(int j = 0; j < num; j++){
            scanf("%d", &id);
            graph[id][i] = true;//信息可以从id流向i
        }
    }
    scanf("%d", &num);
    for(int i = 0; i < num; i++){
        scanf("%d", &id);
        fill(visited, visited + 1002, false);
        amount = -1;//将自己也加进去了 需要减一
        dfs(id, 0);
        cout<<amount<<endl;
    }
    return 0;
}

 

第二搏

Too young,too simple !

使用DFS会有一个隐蔽的错误:参考@日沉云起【pat甲级1076. Forwards on Weibo (30)——BFS+DFS】先膜为敬!

看到这里,果断弃坑,加入BFS阵营!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值