题目链接
题目分析
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;
}