【ACM】- PAT. A1076 Forwards on Weibo【图的遍历】

题目链接
题目分析

1、L即表示最多传递L层
2、所给指向关系是反的,即所给结点号为其父节点
3、结点编号 1-N

解题思路

使用BFS遍历,遍历时记录每个结点的层数

注:不建议用DFS,可能会导致
1、遗漏某些可以更快到达的路径;
2、同一个结点的转发次数被重复计算


AC程序(C++)
/**********************************
*@Author: 3stone
*@ACM: PAT.A1076 Forwards on Weibo
*@Time: 18/8/10
*@IDE: VSCode 2018 + clang++
***********************************/
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>

using namespace std;
const int maxn = 1010;

int N, L, sum; //结点数,最大传播深度, 转发总数
int G[maxn][maxn]; //邻接矩阵
int layer[maxn]; //记录每个结点所在层次
bool inq[maxn] = {false}; //标记结点是够进入队列

void BFS(int u){
    queue<int> q;
    q.push(u);
    inq[u] = true;

    layer[u] = 0; //初始为0层

    while(!q.empty()) {
        int v = q.front();
        q.pop();
        if(layer[v] >= L) break; //超出传递范围,后边必然也超出范围

        for(int i = 1; i <= N; i++){ //遍历子节点
            if(inq[i] == false && G[v][i] == 1) {
                inq[i] = true;
                sum++;
                layer[i] = layer[v] + 1; //子节点层数 +1
                q.push(i);
            }
        }

    }//while
}


int main() {

    int M, K;
    int user_k;
    while(scanf("%d%d", &N, &L) != EOF) {

        //初始化 所有结点无连接
        for(int i = 0; i < maxn; i++) 
            for(int j = 0; j < maxn; j++)
                G[i][j] = 0;  //本题为无权图  

        //输入图信息
        for(int i = 1; i <= N; i++) { //结点标号1-N
            scanf("%d", &M);
            for(int j = 0; j < M; j++) {
                scanf("%d", &user_k);
                G[user_k][i] = 1;
            }
        }
        scanf("%d", &K); //查询数
        for(int i = 0; i < K; i++){ //逐次查询

            //每次查询前都需初始化
            sum = 0;
            for(int i = 1; i <= N; i++) {  //初始均未访问
                inq[i] = false;
                layer[i] = -1;
            }

            scanf("%d", &user_k);
            BFS(user_k); 
            printf("%d\n", sum);    
        }

    }//while

    return 0;
}

AC程序(C++)【摘自《算法笔记》】

邻接表实现

/**********************************
*@Author: 3stone
*@ACM: PAT.A1076 Forwards on Weibo
*@Time: 18/8/10
*@IDE: VSCode 2018 + clang++
***********************************/
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>

using namespace std;

const int maxn = 1010;

struct Node{
    int id, layer;
};

int N;
bool inq[maxn];
vector<Node> Adj[maxn];

int BFS(int u, int L) {
    queue<Node> q;

    Node s;
    s.id = u;
    s.layer = 0;
    q.push(s);
    inq[u] = true;
    int num = 0;

    while(!q.empty()) {
        Node top_node = q.front();
        q.pop();
        int v = top_node.id;

        for(int i = 0; i < Adj[v].size(); i++) {
            Node next_node = Adj[v][i];
            next_node.layer = top_node.layer + 1;
            if(inq[next_node.id] == false && next_node.layer <= L){
                q.push(next_node);  
                inq[next_node.id] = true;
                num++;
            }
        }//for

    }//while

    return num;
}


int main() {

    int L, M, K, user_id;
    Node new_node;

    while(scanf("%d%d", &N, &L) != EOF) {
        //初始化
        for(int i = 0; i < maxn; i++) {
            Adj[i].clear();
            inq[i] = false;
        }

        //输入图信息
        for(int i = 1; i <= N; i++) { //结点标号1-N
            scanf("%d", &M);
            new_node.id = i;
            for(int j = 0; j < M; j++) {
                scanf("%d", &user_id);
                Adj[user_id].push_back(new_node);
            }
        }
        scanf("%d", &K); //查询数
        for(int i = 0; i < K; i++){ //逐次查询

            //每次查询前都需初始化
            memset(inq, false, sizeof(inq));

            scanf("%d", &user_id);
            printf("%d\n", BFS(user_id, L)); 
        }

    }//while

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_26398495/article/details/81607292