算法笔记---[PAT A1076] Forwards on Weibo

题目链接:[PATA 1076] Forwards on Weibo

题目描述:

Weibo is known as the Chinese version of Twitter. One user on Weibo may have many followers, and may follow many other users as well. Hence a social network is formed with followers relations. When a user makes a post on Weibo, all his/her followers can view and forward his/her post, which can then be forwarded again by their followers. Now given a social network, you are supposed to calculate the maximum potential amount of forwards for any specific user, assuming that only L levels of indirect followers are counted.

下面为题目大意:

在微博中,每个用户都可能被若干个其他用户关注。而当该用户发布一条信息时,他的关注者就可以看到这条信息并选择是否转发它,且转发的信息也可以被转发者的关注者再次转发,但同一用户最多只转发该信息一次(信息的最初发布者不会转发该信息)。现在给出N个用户的关注情况(即他们各自关注了哪些用户)以及一个转发层数上限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

输入的第一行表示共有多少个用户,转发的最多层数为多少。
接下来的 n 行
如3 2 3 4 表示当前结点一共关注了3个人,每个人的 id 分别为2 3 4
最后一行表示要查询的结点个数,以及每次查询时起始结点的id

需要注意的是:
该题的结点的id是从 1 开始的

解题思路:
该题很明显是希望我们使用图的广度优先遍历来实现。
首先定义一个结构体

struct UserNode{
	int id;//当前结点的id
	int layer;//当前结点的layer
};

下面为AC代码:

#include
#include
#include
#include//memset函数需要引入该头文件,不然编译不会通过
using namespace std;

const int max_v = 1010;
struct UserNode {//表示用户结点
	int id;//结点编号
	int layer;//当前结点所在层次
};


//************************************
// Method:    bfs 返回最多可以转发的次数
// FullName:  bfs
// Access:    public 
// Returns:   int
// Qualifier:
// Parameter: vector matrix[max_v] 构造的图
// Parameter: int start 起始结点
// Parameter: int layer 最多可以访问的层数
// Parameter: bool * visited 标记当前结点是否被访问
//************************************
int bfs(vector<UserNode> matrix[max_v], int start, int layer, bool* visited) {

	UserNode user_node;
	user_node.id = start;//当前结点 id
	user_node.layer = 0;//当前结点 layer
	queue<UserNode> q;//BFS 队列
	q.push(user_node);
	visited[start] = true;
	int forward_number = 0;//转发次数
	while (!q.empty())
	{
		UserNode top_node = q.front();
		q.pop();
		for (int i = 0;i < matrix[top_node.id].size();i++)
		{
			UserNode next_node = matrix[top_node.id][i];//当前结点指向的下一个结点
			next_node.layer = top_node.layer + 1;//层数+1
			
			if (visited[next_node.id] == false && next_node.layer <= layer)//该结点没有被访问且结点层数小于最多可访问层数
			{
				q.push(next_node);
				visited[next_node.id] = true;
				forward_number++;//转发次数+1
			}
		}
	}
	return forward_number;
}

int main() {
	
	int n, layer;//n 表示结点总数,layer 表示至多可以访问几层
	cin >> n >> layer;

	vector<UserNode> matrix[max_v];
	UserNode user_node;
	int follow_number, follow_id;//follow_number 表示当前当前结点关注的人数,follow_id 表示当前结点 关注的结点编号
	for (int i = 1;i <= n;i++)
	{
		user_node.id = i;//表示当前结点的编号
		cin >> follow_number;//表示当前结点 关注的总人数
		for (int j = 0; j < follow_number;j++)
		{
			cin >> follow_id;//当前结点 关注的结点编号
			//则被关注的人只要发送信息,关注的就可以收到,即有被关注的结点指向关注结点的边
			//如 X 关注了 Y 则只要 Y 发送信息,X 就会收到。即 Y —> X
			matrix[follow_id].push_back(user_node);//表示关注结点在被关注结点上注册。
		}
	}
	//此时有向图已经建立完毕
	int search_number;//表示要查询的结点个数
	cin >> search_number;
	int start;//表示开始结点
	bool visited[max_v];//表示当前结点是否被访问
	for (int i = 0;i < search_number;i++)
	{
		cin >> start;
		memset(visited, false, max_v);
		int result = bfs(matrix, start, layer, visited);
		cout << result << endl;
	}
	system("pause");
	return 0;
}

你可能感兴趣的:(C++,算法笔记,编程练习)