当前位置: 代码迷 >> 综合 >> [PAT A1076]Forwards on Weibo
  详细解决方案

[PAT A1076]Forwards on Weibo

热度:96   发布时间:2023-12-15 06:08:33.0

[PAT A1076]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.

输入格式

Each input file contains one test case. For each case, the first line contains 2 positive integers: N (≤1000), the number of users; and L (≤6), the number of levels of indirect followers that are counted. Hence it is assumed that all the users are numbered from 1 to N. Then N lines follow, each in the format:

M[i] user_list[i]

where M[i] (≤100) is the total number of people that user[i] follows; and user_list[i] is a list of the M[i] users that followed by user[i]. It is guaranteed that no one can follow oneself. All the numbers are separated by a space.

Then finally a positive K is given, followed by K UserID's for query.

输出格式

For each UserID, you are supposed to print in one line the maximum potential amount of forwards this user can trigger, assuming that everyone who can view the initial post will forward it once, and that only L levels of indirect followers are counted.

输入样例

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.题目大意:首先输入n,L,n表示用户数,L表示查询的深度(即能被转发几次)。然后n行,第i行表示第i个用户,对于每一行,首先输入t,表示该用户有几个关注列表,然后分别输入他们的编号。最后一行输入t,表示要查询的结点的个数,然后输入t个结点,分别输出他们的消息能被多少人转发。(如果一个用户A被用户B关注,那么B可以转发A的消息)

2.这道题我一开始使用的是DFS,发现是行不通的,只能拿到22分,然后我阅读了《算法笔记》,晴神给出了说明,为什么不能使用深度优先搜索。这里我就使用晴神的用例讲解一下:

假设深度为3:

一开始图是这样的:

然后根据DFS,首先访问1,将1设为已访问,此时level=0

然后是访问2,将2设为已访问,此时level=1

然后访问3,4,即访问到4的时候,level=3,发现=maxlevel=3,停止向下继续访问

但是这个时候,1访问完2,却不能再访问4了,因为4已经被访问过了,这样5本来是可以达到的,但是由于是深度搜索,这里导致答案错误了

3.具体代码如下:

#include<iostream>
#include<queue>
#include<vector>
using namespace std;
const int maxn = 1010;
struct node {  //每个node记录结点的编号,和该结点对应的层次int no;int level;
};
int n, l;
vector<node> v[maxn];  //图的邻接表写法
bool visit[maxn] = { false };  //visit数组,一开始设为false
void BFS(int i, int& num);  //广度优先搜索
int main()
{scanf("%d%d", &n, &l);for (int i = 1; i <= n; i++) {int t, temp;scanf("%d", &t);for (int j = 1; j <= t; j++) {scanf("%d", &temp);v[temp].push_back({ i,0 });}}int k;scanf("%d",&k);for (int i = 1; i <= k; i++) {int temp, num = 0;scanf("%d", &temp);BFS(temp, num);for (int j = 1; j <= n; j++) visit[j] = false; //将visit重置,以免出错printf("%d\n", num - 1);}return 0;
}
void BFS(int i, int& num) {      //BFS写起来较麻烦,没有DFS好理解,但是这题还是只能用DFSqueue<node> que;      //首先创建一个队列visit[i] = true;      //设置初始结点visit为truenum++;                //记录连通的图的结点个数que.push({ i,0 });    //把第一个结点压入队列while (!que.empty()) {node t = que.front();que.pop();int u = t.no;     //记录队头结点编号for (int j = 0; j < v[u].size(); j++) {  //对于每一条边通向的结点node next = v[u][j];next.level = t.level + 1;if (visit[next.no] == false && next.level <= l) { 如果下一个结点没有被访问,且层数不超过lque.push(next);visit[next.no] = true;num++;}}}
}