PAT-ADVANCED1076——Forwards on Weibo

探讨PAT-ADVANCED竞赛中1076微博转发问题的解决方案,利用图的广度优先遍历算法,计算用户发布信息在限定层内可能达到的最大转发量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我的PAT-ADVANCED代码仓:https://github.com/617076674/PAT-ADVANCED

原题链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805392092020736

题目描述:

题目翻译:

1076 微博转发

众所周知,微博是中国版的推特。微博上的一个用户可能有很多的关注者,同样也可以关注其他许多人。因此,一张社交网络就由关注与被关注的联系所形成。一旦用户在微博上发了一条信息,他/她的所有关注者都可以查看并转发这条信息,同样这条信息能再次被转发者的关注者所再次转发。现在考虑一个社交网络,假设只考虑L层的间接转发者,你需要计算出所有用户所发信息的最大可能转发量。

输入格式:

每个输入文件包含一个测试用例。在每个测试用例中,第一行包含两个正整数:N(<= 1000),用户总数;L,需要考虑的间接转发者的最大层数。这里我们假设所有的用户都被标记为1~N。接下来的N行格式如下:

M[i] user_list[i]

这里M[i](<= 100)是用户user[i]关注的总人数;user_list[i]是M[i]个被用户user[i]所关注的编号。题目保证自己不能关注自己。所有的数字被一个空格分隔。

最后一行给出了一个正整数K,后面跟着K个需要查询的用户ID。

输出格式:

对每一个用户ID,你需要在1行中打印出这个用户的一条信息所能触发的最大转发量。这里我们假设所有人一看到这条信息就会立刻转发,且只考虑L层之内的间接转发者。

输入样例:

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

输出样例:

4
5

知识点:图的广度优先遍历

思路:图的广度优先遍历

注意点:

(1)用户的编号为1~N,而不是从0开始。

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

步骤如下述所示:

(1)首先考虑如何建图。由于题目给定的数据是用户关注的情况(而不是被关注的情况),因此如果用户X关注了用户Y,则需要建立由Y指向X的有向边,来表示Y发布的消息可以传递到X并被X转发。

(2)在建图完毕后,使用BFS得到需要的结果。将节点编号和层号建立成结构体,然后控制遍历层数不超过L。

C++代码:

#include<iostream>
#include<queue>

using namespace std;

//用一个节点来将层级信息和节点编号信息封装在一起 
struct node{
	int number;
	int level;
	node(int _number, int _level) : number(_number), level(_level) {}	//构造函数 
};

int n;	//用户总数
int l;	//需要考虑的转发层数
int graph[2001][2001] = {0};	//有向图,0代表两者之间被有关注与被关注的关系,graph[i][j] = 1表示用户j关注了用户i 

void bfs(int nowVisit, int& count);

int main(){
	cin >> n >> l;
	int m, f;	//一个人的关注数m,被关注的人f 
	for(int i = 0; i < n; i++){
		cin >> m;
		for(int j = 0; j < m; j++){
			cin >> f;
			graph[f - 1][i] = 1;
		}
	}
	int k;
	cin >> k;
	int query;
	for(int i = 0; i < k; i++){
		cin >> query;
		int count = 0;
		bfs(query - 1, count);
		cout << count << endl;
	}
	
	return 0;
}

void bfs(int nowVisit, int& count){
	bool visited[2001] = {false};	//标记数组,标记某节点是否已被访问
	queue<node> q;
	q.push(node(nowVisit, 0));
	visited[nowVisit] = true;
	while(!q.empty()){
		node u = q.front();
		q.pop();
		for(int i = 0; i < 2001; i++){
			if(!visited[i] && graph[u.number][i] != 0){
				q.push(node(i, u.level + 1));
				if(u.level + 1 <= l){
					count++;
				}
				visited[i] = true;
			}
		}
	}
}

C++解题报告:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值