HDU

来源:互联网 发布:js 访问json第n个 编辑:程序博客网 时间:2024/06/06 13:04

题目:

HDU - 4039 The Social Network

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
-
-


题意:

输入N种朋友关系,指的是这个人互为朋友,查找Q次,查找的是这个人被推荐的朋友。

分析:

被推荐的人要满足一下的条件:A有朋友BCDE,BCDE各自除了A和A的朋友之外的人中重合度最高的就是要推荐给A的,按照一定顺序排列。这样的话开两个map一个是< string, int>一个是< int, string>,分别对应名字和序号,序号和名字,输入朋友关系的时候,先存入2个map,然后再在vector< int>中建立双向节点以供查找。这道题使用BFS在深度为二的时候,将所有出现过的人都以下标的形式存入一个数组中表示次数,并且更新出现次数最多的,最后出现最多的放入set然后输出就OK。


代码如下:

#include <cstdio>#include <iostream>#include <map>#include <vector>#include <cstring>#include <queue>#include <set>using namespace std;map<string, int> ID;       //名字查找序号(用于存储)map<int, string> RD;       //序号查找名字(用于输出)vector<int> e[2005];       //建立节点关系struct ff{    int id;        //当前ID    int step;        //查找深度};int time[2005];        //出现次数int mx;        //出现最大次数void bfs(int i)        //传入要查找的人{    queue<ff> q;    q.push(ff{i, 0});        //深度为1,ID为f推入队列    while(!q.empty())    {        ff v = q.front();        q.pop();        if(v.step < 2)        //深度小于2时        {            for(auto &k : e[v.id])            {                if(v.step == 0)        //深度为0时直接推入                {                    q.push(ff{k, v.step + 1});                }                if(v.step == 1 && k != i)        //深度为1时推入要求ID不与被查询人相同,就是不把自己推荐给自己                {                    int ll = 0;                    for(auto &l : e[i])    //确保被推荐人不是被查询人的朋友,即不把被查询人的朋友推荐给被查询人                    {                        if(k == l)                            ll++;                    }                    if(ll == 0)    //同时满足上面两点就入队                        q.push(ff{k, v.step + 1});                }            }        }        if(v.step == 2)        //深度为2,就是符合条件的人        {            time[v.id]++;        //查找出现次数最多的            mx = (mx > time[v.id]) ? mx : time[v.id];        }    }    while(!q.empty())   q.pop();}int main(){    int T;    scanf("%d", &T);    for(int i = 0; i < T; i++)    {        int N, Q;        printf("Case %d:\n", i + 1);        cin >> N >> Q;        //cout << "Case " << i + 1 << ": " << endl;        int cnt = 0;        for(int j = 0; j <= 2 * N; j++)            e[j].clear();        ID.clear();        RD.clear();        for(int j = 0; j < N; 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 < Q; j++)        {            string str3;            cin >> str3;            memset(time, 0, sizeof(time));            mx = 0;        //初始化为0            bfs(ID[str3]);            if(mx == 0)        //没有可以推荐的就输出-            {                cout << "-" << endl;            }            else            {                set<string> ss;                for(int k = 0; k < 2005; k++)                {                    if(time[k] == mx)                        ss.insert(RD[k]);                }        //上述操作是将出现次数最多的都放入set                for(set<string>::iterator item = ss.begin(); item != ss.end(); item++)                {                    set<string>::iterator item2 = item;                    item2++;                    if(item2 != ss.end())    //控制输出格式                        cout << *item << " ";                    if(item2 == ss.end())                        cout << *item << endl;                }            }        }    }    return 0;}

一定要注意格式,一定要注意格式,一定要注意格式!!!重要的事说三遍,为了一个格式的问题改了一上午……令人绝望。