HDU4039 The Social Network(bfs)

The social network system (SNS) helps people to keep connecting with their friends. Every user in SNS has a friends list. The user can read news posted by the users in his friends list. Friend relation is symmetric - if A is a friend of B, B is always a friend of A.

Another important function in SNS is friend recommendation. One effective way to recommend friends is recommend by mutual friends. A mutual friend between two users A and B, is a user who is a friend of both A and B. A user can not be a friend of himself. For a specific user A, the system will recommend the user who is not himself or his friend, and has mutual friends with A. If more than one such user exists, recommend the one has most mutual friends with A. If still a tie exists, output all of them.

Input
The first line is a integer T (T≤100), the number of test case.
The beginning of each test case is two integers N and Q, the number of friend relationship and the number of query. 1 ≤ N, Q ≤ 1000
The following N lines each contain two different names separated by a single space. Each name consisted by only lowercase letters, and its length is less than or equal to 15. This means the two users are friends. No friend relationship will be given more than once.
The following Q lines each describe a query. Each line contain one user name. The data guarantee that this name appears at least once in above N lines.
Output
For each case, you should output one line containing “Case k: ” first, where k indicates the case number and counts from one. Then for each query, output one line, contains one or more names of recommended friends, separate by a single space, sorted by alphabetical order. If no persons can be recommended, output one line contains “-”.
Sample Input

1
10 11
hongshu digua
yingying hongshu
xmm hongshu
huaxianzi xmm
tangjiejie huaxianzi
xhmz yingying
digua xhmz
zt tangjiejie
xmm lcy
notonlysuccess ljq
hongshu
digua
yingying
xmm
huaxianzi
tangjiejie
xhmz
zt
lcy
notonlysuccess
ljq

Sample Output

Case 1:
xhmz
yingying
digua
digua tangjiejie yingying
hongshu lcy zt
xmm
hongshu
huaxianzi
hongshu huaxianzi
-
-
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<iterator>
#include<set>
#include<map>
using namespace std;

map<string, int> ID;    //名字到序号(存储)
map<int, string> RD;    //序号到名字(输出)
vector <int> e[2005];   //建立节点
int num[2005];          //该朋友的朋友的名字出现次数
int mx;                 //出现最大次数

struct p
{
    int id;        //当前ID
    int step;      //查找深度(只能朋友的朋友,即深度为2)
};
void bfs(int x)     //传入要查找的人
{
    queue<p> q;
    q.push(p{x, 0});//深度为1,ID为x推入队列
    while(!q.empty())
    {
        p v = q.front();
        q.pop();
        if(v.step<2){//深度小于2时
            for(auto &k : e[v.id]){
                if(v.step == 0){//深度为0时直接推入
                    q.push(p{k, v.step + 1});
                }
                if(v.step == 1 && k != x)        //深度为1时推入要求ID不与被查询人相同,就是不把自己推荐给自己
                {
                    int ll = 0;
                    for(auto &l : e[x])    //确保被推荐人不是被查询人的朋友,即不把被查询人的朋友推荐给被查询人
                    {
                        if(k == l)
                            ll++;
                    }
                    if(ll == 0)    //同时满足上面两点就入队
                        q.push(p{k, v.step + 1});
                }
            }
        }
        if(v.step == 2)        //深度为2,就是符合条件的人
        {
            num[v.id]++;        //查找出现次数最多的
            mx = (mx > num[v.id]) ? mx : num[v.id];
        }
    }
    while(!q.empty())   q.pop();
}
int main()
{
    int n, a, b;
    cin >> n;
    for(int i=0; i<n; i++){
        printf("Case %d:\n", i+1);
        cin >> a >> b;
        int cnt=0;
        for(int j=0; j<2*a; j++){
            e[j].clear();
        }
        ID.clear();
        RD.clear();
        for(int j=0; j<a; j++){
            string str1, str2;
            cin >> str1 >> str2;
            if(!ID[str1]){
                ID[str1]=++cnt;
                RD[cnt]=str1;
            }
            if(!ID[str2]){
                ID[str2]=++cnt;
                RD[cnt]=str2;
            }
            int u=ID[str1], v=ID[str2];
            e[u].push_back(v);
            e[v].push_back(u);
        }
        for(int j=0; j<b; j++){
            string str3;        //输入每个人名字
            cin >> str3;
            memset(num, 0, sizeof(num));
            mx = 0;
            bfs(ID[str3]);
            if(mx == 0){
                printf("-\n");//没有推荐的就输出
            }
            else{
                set<string>s;
                for(int k=0; k<2005; k++){
                    if(num[k] == mx)
                        s.insert(RD[k]);
                }//上述操作是将出现次数最多的都放入set
                for(set<string>::iterator it = s.begin(); it != s.end(); it++){
                    set<string>::iterator it1 = it;
                    it1 ++;
                    if(it1 !=s.end())
                        cout << *it << " ";
                    if(it1 == s.end())
                        cout << *it << endl;
                }
            }
        }
    }
    return 0;
}

头疼,bfs学的和**一样,此代码近乎于抄了。。。深感绝望。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值