原题目: 1076 Forwards on Weibo (30 分).
题意
-
一个微博用户有很多粉丝,也可能关注其他用户,由此建立了社交网络。当一个用户发了一条微博,ta的粉丝可以查看并转发,并且可以再被粉丝的粉丝转发。现给出一个社交网络,计算每个用户的微博转发量的最大可能值,假设计算到L层间接粉丝。
-
给出用户数量N(≤1000,从1开始编号)和间接粉丝层数L(≤6);接着N行,给出每人的关注量M以及关注对象ID(不能关注自己);最后给出正数K,以及K个待询问的用户ID。
-
👉对这K个用户,计算每人可以引发的最大转发量(每人转发一次)。
分析
- 题意分析:图的带层数的广度优先搜索。
- 图的存储:关注与被关注是有向的,用邻接表存储有向图;题目要求算的是粉丝数,而给的是关注的人的id,存储的时候需要注意存储每人的粉丝,方便后面遍历。
注意点
- 关于层次:根据已给样例,层数包括第一层粉丝直到上限第L层。
- 使用DFS遍历容易出错:存在某用户由另一条路径可以在L层内访问到,但DFS却没有发现的情况;写的不够好还会超时。
知识点
- 图的带层数的广度优先搜索。
词汇
CHUNK | 释义 |
---|---|
forward one’s post | 转发微博 |
CODE
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int n, l, m, k;
struct node{ //带层数的广度优先
int id, layer;
};
vector<vector<int>> v; //大小用resize声明则元素类型需要如此定义
int BFS(node tnode); //返回最大转发量
int main()
{
cin >> n >> l;
v.resize(n+1);
//生成图的邻接表
for ( int i=1; i<=n; i++ ){
cin >> m;
for ( int j=0; j<m; j++ ){
int tmp;
cin >> tmp;
v[tmp].push_back(i); //tmp→(关注)→i
}
}
//统计k个用户的粉丝量
cin >> k;
int tid;
for ( int i=0; i<k; i++ ){
cin >> tid;
node tnode = {tid, 0}; //从直接粉丝开始算第一层
//遍历指定顶点所在连通块
printf("%d\n", BFS(tnode));
}
return 0;
}
int BFS(node tnode){
bool inq[1010] = {false}; //入队情况
queue<node> q;
q.push(tnode); //初始元素入队
inq[tnode.id] = true; //针对id标记入队情况
int cnt = 0; //计算转发量
while( !q.empty() ){
node top = q.front(); //取出队首元素
q.pop(); //队首元素出队
int topid = top.id; //队首元素id
for ( int i=0; i<v[topid].size(); i++ ){
int nextid = v[topid][i]; //邻接顶点id
if ( inq[nextid]==false && top.layer<l ){ //有层次限制
node next = {nextid, top.layer+1};
q.push(next); //往邻接顶点遍历,层次+1
inq[next.id] = true; //标记
cnt++;
}
}
}
return cnt;
}