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
题目大意:给出每个用户关注的人,求一个用户发了条微博后,会有多少人转发
一开始用DFS,最后一个点运行超时。其实就算不超时,它也不对,因为在这里一个结点可以被访问多次
DFS代码
#include<bits/stdc++.h>
using namespace std;
vector<vector<int>> follow;
vector<int> temp;
set<int> forwardMan;
bool visit[1010];
int nodeNum, level,layer[1010];
void DFS(int node,int height){
temp.push_back(node);
if(height==level)
return;
visit[node] = true;//当前结点置为已访问
layer[node] = height;//更新遍历时所处层数
for (int i = 0; i < (int)follow[node].size();i++){//遍历当前结点的邻接结点
if(visit[follow[node][i]]==false||layer[follow[node][i]]>height+1)
DFS(follow[node][i], height + 1);
}
}
int main(){
cin >> nodeNum >> level;
follow.resize(nodeNum+1);
int a, b;
for (int i = 1; i <= nodeNum;i++){
cin >> a;
for (int j = 0; j < a;j++){
cin >> b;
follow[b].push_back(i);
}
}
scanf("%d", &a);
for (int i = 0; i < a;i++){
scanf("%d", &b);
DFS(b, 0);
for (int j = 0; j < (int)temp.size();j++)
forwardMan.insert(temp[j]);
printf("%d\n", (int)forwardMan.size()-1);//只算转发的人数第一个不用
fill(visit, visit + 1010, false);
forwardMan.clear();
temp.clear();
}
return 0;
}
后改用BFS
算法设计:设置结构体存储用户id和所在层数,visit数组标记该结点是否被访问,每个结点只能被访问一次。当所在层数等于给出的最大转发层数时,循环停止。利用广度优先搜索的模板实现
AC代码
#include<bits/stdc++.h>
using namespace std;
vector<vector<int>> follow;//存储关注用户的人的信息
struct node{
int id, layer;
};
int nodeNum, level;
int BFS(node topnode){
int cnt = 0;//只算转发的人数,第一个结点压入时不用设为1
bool visit[1010]={false};
queue<node> x;
x.push(topnode);
visit[topnode.id] = true;
while(!x.empty()){//队列不空循环执行
/*出队,依次检查出队结点的所有邻接结点,访问没有被访问过的邻接结点,并将其入队*/
node tempNode = x.front();
x.pop();
for (int i = 0; i < follow[tempNode.id].size();i++){
if(visit[follow[tempNode.id][i]]==false&&tempNode.layer<level){
node next = {follow[tempNode.id][i], tempNode.layer + 1};
x.push(next);
visit[follow[tempNode.id][i]] = true;
cnt++;
}
}
}
return cnt;
}
int main(){
cin >> nodeNum >> level;
follow.resize(nodeNum + 1);//这一步不要忘记,不然会段错误,因为声明的时候没有分配空间
int a, b;
for (int i = 1; i <= nodeNum;i++){
cin >> a;
for (int j = 0; j < a;j++){
cin >> b;
follow[b].push_back(i);//注意输入的是用户关注的人,转化为关注用户的人
}
}
cin >> a;
for (int i = 0; i < a;i++){
cin >> b;
node topnode = {b, 0};
printf("%d\n", BFS(topnode));
}
return 0;
}