題目連接:[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;
}