1076 Forwards on Weibo (BFS层次遍历)

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

 

题目大意:微博中一博主有若干粉丝,博主发布微博,粉丝们一定会进行转发,因此这些粉丝们的粉丝也会看到博主的的微博,现在给出一系列微博用户的id,以及他们关注的人,给定某个id,求该id发一个微博,在L层内会有多少人看到这个微博

 

层的意思如图所示,如果L等于3,那么将会有4个人看到这个微博

 

思路:使用BFS进行遍历,规定遍历的层数。设定两个变量,一个temp用来保存当前层所有节点的儿子节点中最后一个儿子节点,另一个是end,用来保存当前层的最后一个节点。

若从队列中取出来的节点号等于end,那么则让level+1,并更新end为temp(当前层结点遍历完了之后,temp保存的是本层节点的儿子节点中的最后一个,这个节点一定是下一层的最后一个节点)

 

#include<bits/stdc++.h>
using namespace std;
vector<int>e[1010]; //存图
int vis[1010];      //bfs标记数组
int hasCount[1010]; //标记统计过的节点
int n,l;
int main()
{
    int k,id;
    cin>>n>>l;
    for(int i=1; i<=n; i++)
    {
        cin>>k;
        for(int j = 1; j<=k; j++)
        {
            cin>>id;
            e[id].push_back(i);    //第i个人关注了id意味着id发的消息可以传到第i个人这,因此建立从id到i的边
        }
    }
    int q,s,count=0;
    cin>>q;
    queue<int> qu;//bfs队列
    while(q--)
    {
        int temp=s; //记录当前层级所有节点中最后一个儿子节点
        int end=s;  //记录当前层级最后一个节点
        int level=0;//表示当前层级
        count=0;    //记录间接粉丝数
        cin>>s;
        qu.push(s);
        vis[s]=1;   
        level=0;    //初始化当前层数为0
        while(!qu.empty()&&level<l)
        {
            int t = qu.front();
            qu.pop();   //队首元素出队
            for(int i = 0; i<e[t].size(); i++)
            {
                int x = e[t][i];
                if(vis[x]==1)
                    continue;
                qu.push(x);
                vis[x]=1;
                if(level+1>0)   //当前节点层数为level,他的儿子节点层数为level+1
                {
                    if(hasCount[x]==0)  //若该节点未被统计过则统级它
                    {
                        count++;
                        hasCount[x]=1;
                    }

                }
                temp=x;                 //记录最后一个儿子节点
            }
            if(t==end)                  //当前节点是本层最后一个节点
            {
                level++;                //层数加一
                end=temp;               //更新当前层的最后一个节点
            }
        }
        
        while(qu.size())
        {
            qu.pop();
        }
        cout<<count<<endl;
        memset(vis,0,sizeof(vis));
        memset(hasCount,0,sizeof(hasCount));
    }
    return 0;
}

提交结果

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值