浙大pat 牛客网 1011 Forwards on Weibo (30) 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, allhis/her followers can view and forward his/her post, which can then beforwarded again by their followers.  Nowgiven a social network, you are supposed to calculate the maximum potentialamount of forwards for any specific user, assuming that only L levels of indirectfollowers are counted.



输入描述:

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

M[i] user_list[i]

where
M[i] (<=100) is the total number ofpeople that user[i] follows; and user_list[i] is a list of the M[i] users that are followed by user[i].  It is guaranteed that no one can followoneself.  All the numbers are separatedby 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 potentialamount of forwards this user can triger, assuming that everyone who can viewthe initial post will forward it once, and that only L levels of indirectfollowers 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

题目中的第一个隐藏条件就是forward不是指微博的转发次数,而是指收到微博的人的个数,这一点只有通过数据才能看出来,所以说做题之前一定要先看数据

然后这一题要求只统计非直接粉丝的数量indirect就是这个意思

我做这一题思路不是很正确,首先这一题有极端数据,就是L为1,我没有考虑到,其实使用三指针的数组模拟广度优先遍历的正确方法是能够避免这个问题的,

以后记住三指针模拟广度优先遍历的正确写法

对于这种需要获得层数的广度优先遍历,有三种方法,一种是三指针,这种是最复杂的,然后还有一种是使用两个队列,第一个队列取,第二个队列如,复杂度比第一个简单,但是时间长一点,可以考虑,第三种就是队列中的元素使用自己写的数据结构,保存节点的层数,这种方法是最好的,以后在做这种类似的题目的时候使用这种方法

#include <iostream>
#include <memory.h>
using namespace std;


bool theEdges[1003][1003] = {false};
bool vst[1003] = {false};
int theStack[1003];
int _left=0,_right=0;
int N,L;
int lIndex;
int BFS(int p)
{
	if(L==0) return 0;
	_left = _right = 0;
	int theForwardCount=0;
	memset(vst,false,sizeof(vst));
	vst[p]=true;
	for(int i=1;i<=N;i++)
	{
		if(theEdges[p][i])
		{
			theStack[_right++]=i;
			vst[i]=true;
			 theForwardCount++;
		}
	}
	if(L==1) return theForwardCount;

	_left=_right;
	lIndex=1;
	int index=0;
	int u;

	while(1)
	{
	   while(index<_left)
	   {
		  u=theStack[index++];
		  for(int i=1;i<=N;i++)
		  {
			  if(theEdges[u][i])
			  {
				 
				  if(!vst[i])
				  {
					  theStack[_right++] = i;
					  vst[i]=true;
					   theForwardCount++;
					  
				  }
			  }
		  }
	   }
	   lIndex++;
	   if(index == _right || lIndex >= L) break;
	   _left = _right;
	}
	return theForwardCount;
}

int main()
{
	int a,b;
	int i,j;

	cin>>N>>L;
	for(i=1;i<=N;i++)
	{
		cin>>a;
		for(j=0;j<a;j++)
		{
			cin>>b;
			theEdges[b][i]=true;
		}
	}
	cin>>a;
	for(i=0;i<a;i++)
	{
		cin>>b;
		cout<<BFS(b)<<endl;
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值