PAT甲级刷题记录——1076 Forwards on Weibo (30分)

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.

Input Specification:

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.

Output Specification:

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.

Sample Input:

7 3
3 2 3 4
0
2 5 6
2 3 1
2 3 4
1 4
1 5
2 2 6

Sample Output:

4
5

思路

这题因为之前看过题目,知道题目意思哈,所以做起来很快(其实要是完全理解题目意思的话,甲级的题目写代码还是挺快的,感觉主要时间花在英语的阅读理解上面……)。

题目的大概意思是:给你一个数N,代表有N个用户,然后L是消息传播层数的上限(发出消息的那个人算0层,至于我是怎么知道的,算一下样例就知道了……),然后给出N行,第i行就是第i个人关注注意:这里不是他的粉丝,而是他关注的人!!)的用户编号(比如第一行3 2 3 4,意思是,用户1关注了3个人,这3个人分别是2、3、4,第三行2 5 6,意思是用户3关注了2个人,分别是5、6,后面同理……),然后如果一个人发微博的话,那么他的粉丝可以转发(假设每个人只转发一次),然后粉丝的粉丝又可以转发……最后给你一个用户编号,问,当这个用户发消息时,且在转发层数到L层时,共有多少个用户转发了该消息(最后一行2 2 6的意思是,要查询2个人,第一个是用户2,第二个是用户6)。

为了表示消息传播的路径,那么显然是后面的人指向前面的人(比如用户1关注了2、3、4,因为用户1是他们三个的粉丝,那么消息传播路径是2->1、3->1、4->1),于是就能构建出一个有向图。

然后再用BFS对这个有向图进行搜索就行了,这里要注意的是,因为要判断转发层数的关系,因此BFS里的队列应该是结构体node类型(包括编号id和层数layer),于是在对top相邻顶点遍历的时候,需要判断是否已入队,如果还未入队,那么相邻顶点的层数就是top层数+1,然后再入队就好了。

因为结果要求输出的是所有转发用户的数目,因此直接用一个引用num传入函数即可(每次想要入队一个元素时,num先++,但是入队起点的时候不用加,因为发消息的那个人不算),当BFS函数结束时,得到的num就是参与转发的所有用户数。

代码

#include<cstdio>
#include<stdlib.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<string>
#include<string.h>
#include<iostream>
using namespace std;
const int maxn = 1010;
const int INF = 123123123;
struct node{
    int id;
    int layer;
};
vector<int> G[maxn];
bool inq[maxn] = {false};
void bfs(int s, int L, int &num){
    memset(inq, false, sizeof(inq));
    queue<node> q;
    node start;
    start.id = s;
    start.layer = 0;
    q.push(start);
    inq[s] = true;
    while(!q.empty()){
        node top = q.front();
        q.pop();
        if(top.layer==L) return;
        for(int i=0;i<G[top.id].size();i++){
            int v = G[top.id][i];//v是当前top可达的顶点
            if(inq[v]==false){
                num++;
                node tmpv;
                tmpv.id = v;
                tmpv.layer = top.layer+1;
                q.push(tmpv);
                inq[v] = true;
            }
        }
    }
}
int main(){
    int N, L;
    scanf("%d%d", &N, &L);
    for(int i=1;i<=N;i++){
        int M;
        scanf("%d", &M);
        for(int j=0;j<M;j++){
            int tmp;
            scanf("%d", &tmp);
            G[tmp].push_back(i);//消息传播:tmp->i
        }
    }
    int K;
    scanf("%d", &K);
    for(int i=0;i<K;i++){
        int tmpQuery;
        scanf("%d", &tmpQuery);
        int num = 0;
        bfs(tmpQuery, L, num);
        printf("%d\n", num);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值