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
微博被称为中国版推特。一个微博用户可能有很多粉丝,也可能关注很多其他用户。因此,与追随者关系形成了社交网络。当用户在微博上发帖时,他/她的所有粉丝都可以查看和转发他/她的帖子,然后他们的粉丝可以再次转发。现在给定一个社交网络,您应该计算任何特定用户的最大潜在转发量,假设只计算 L 级间接关注者。
输入规范:每个输入文件包含一个测试用例。对于每种情况,第一行包含 2 个正整数:N(≤1000),用户数; L(≤6),计算的间接追随者的级别数。因此假设所有用户的编号从 1 到 N。然后是 N 行,每行的格式为:M[i] user_list[i]
其中 M[i] (≤100) 是user[i]关注的总人数; user_list[i] 是 user[i] 之后的 M[i] 个用户的列表。保证没有人可以关注自己。所有数字都用空格分隔。然后最后给出一个肯定的K,接着是K个UserID's用于查询。
输出规范:对于每个 UserID,您应该在一行中打印该用户可以触发的最大潜在转发量,假设每个可以查看初始帖子的人都会转发一次,并且只计算 L 级间接关注者.
思考:
什么叫做L 级间接关注者?
间接关注者就是粉丝的粉丝的意思,人1有了粉丝1,那个粉丝1如果有了粉丝2,那粉丝2也就间接的关注了人1,如此类推。L层数就是最大能够进行多少次间接关注。
用户关注了人,那这些被关注的人就会给用户推送信息
然后如果一个人发微博的话,那么他的粉丝可以转发(假设每个人只转发一次),然后粉丝的粉丝又可以转发……,L就是规定最多能传多少层,也就是粉丝与粉丝间传递的转发多少次,超过的就不算了。最后给你一个用户编号,问,当这个用户发消息时,且在转发层数到L层时,共有多少个用户转发了该消息(最后一行2 2 6的意思是,要查询2个人,第一个是用户2,第二个是用户6)。
用户作为顶点,然后找该用户的粉丝。然后再找粉丝1的粉丝有多少个,如此循环,到第L层结束。
(最重要的就是把用户与粉丝,还有关注者,关注者关注的人关注的人,还有被关注者之间的区别--也就是题目所表达的意思理解好,不要混淆,不然就是错解--因为插入数据的时候这个正确与否很重要,第一步都错后面没法讲)
不需要去关心最开始的被关注者关注了谁,因为如果最开始的用户关注的人他们是互相关注的,那一定会出现在该用户的粉丝中!所以直接往下找就行了,不需要往上找。
算法其实也是挺好理解的,就是题目表达真的难懂。每次理解题目都麻了,出题老师的思维逻辑就真的是鬼才。
AC
#include<iostream>
#include<string>
#include<map>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
struct node
{
int id;
int layer=0;
};
vector<int>G[1010];
int num = 0;
int n, L;
void bfs(int s)
{
bool inq[1010] = { false };
node start;
start.id = s;
start.layer = 0;
inq[s] = true;//不能关注自己
queue<node>q;
q.push(start);
while (!q.empty())
{
node top = q.front();
q.pop();
if (top.layer == L)
return;//如果层数已经到了L,就不再往下一层遍历了,直接结束。
for (int i = 0; i < G[top.id].size(); i++)
{
if (inq[G[top.id][i]] == false)
{
num++;
node v;
v.id = G[top.id][i];
//v.layer += 1; err
//是当前层数加1,不是每次新创建一个node在0的基础上加1!
//这才能实现叠加继承,每次都是新的怎么继承!
v.layer = top.layer + 1;
inq[G[top.id][i]] = true;
q.push(v);
}
}
}
}
int main()
{
cin >> n >> L;
for (int i = 1; i <= n; i++)
{
int m;
cin >> m;
for (int j = 0; j < m; j++)
{
int tmp;
cin >> tmp;
G[tmp].push_back(i);
//插入被关注者对应的直接关注者;
}
}
int k;
cin >> k;
for (int i = 0; i < k; i++)
{
int tmpQuery;
num = 0;//重置num;
cin >> tmpQuery;
bfs(tmpQuery);
cout << num << endl;
}
return 0;
}
解析
#define _CRT_SECURE_NO_WARNINGS
#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
//下标表示被关注者。插入的数据表示关注者
//只有关注者才可以转发数据,自己本身不可以转发.
//user关注的人数,那么那些人都是被关注者
//也就是关注人数的列表都相当于被关注者!
}
}
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);
//由输入的所要查找的用户作为起点,
//使用bfs查找这张图究竟联系了多少个粉丝,
// 也就是找到究竟有多少个间接关注者,那就逐个数据一层层查找就行了
// 条件就是题目要求的用户,这张图中能联系起来的粉丝都算间接关注者.
// 然后输出结果就行了
// 当然前提就是满足在L层之内,超过就不算了
//因为bfs就是层序.
}
return 0;
}
//