题目链接:[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<iostream>
#include<vector>
#include<queue>
#include<string.h>//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<UserNode> 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;
}