HDU4039 The Social Network(bfs)

本文介绍了一种基于社交网络的好友推荐系统实现方法,重点在于通过寻找共同好友来推荐新朋友。采用广度优先搜索算法找出特定用户的二度连接好友,并推荐那些与目标用户拥有最多共同好友的用户。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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学的和**一样,此代码近乎于抄了。。。深感绝望。。。

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建与发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建与发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排与可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值