算法筆記---[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<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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章