【map+字典序】hdu 4039 The Social Network
题目链接:hdu 4039 The Social Network
题目大意
模拟一个社交网络系统,先给你n个朋友关系,对每个人,系统会推荐给他一些人给他交朋友,系统推荐的是:他朋友的朋友且与他不是朋友,而且只推荐他最多共同朋友的朋友,如果会推荐多个,按照字典序从小到大输出,如果一个也不推荐输出“-”
熟练map映射:字典序本身map容器里的关键字就是按照字典序存储的,所以最后只要遍历一遍容器,把满足题意的字符串输出即可。
说一下思路
- (1)首先vector建树,无向图,map对字符串作映射,相当于编号。注意vector存储空间是两倍的点数,笔者在这里初始化WA了!QAQ;
- (2)暴力查找O(N^2),数据量不大的:首先标记ok1[]—与A是朋友的true;接着标记ok2,表示A的朋友的朋友,for两圈,期间维护一个最大值dp-与A的有共同朋友的最大值;最后,遍历Map,查找是否A的朋友的朋友、且与A不是朋友、且有A有最多的共同朋友,,好绕口(ㄒoㄒ),找到后就输出即可
参考代码
/*====================================*\
|* map + 字典序 + 图的邻接表存储 *|
\*====================================*/
/*Author:Hacker_vision*/
#include<bits/stdc++.h>
#define clr(k,v) memset(k,v,sizeof(k))
#define eps 1e-8
#define ll long long
using namespace std;
const int _max = 1e3 + 10;
int n,Q,dp,ok2[_max<<1];
bool ok1[_max<<1];
string s1,s2;
vector<int>child[_max<<1];//vector邻接表存储图,2倍边数~!!
map<string,int>mp;
map<string,int>::iterator it;
bool query(string s){//暴力查找O(N^2),v是u的朋友,x是v的朋友且不是u的朋友
int u = mp[s];//字符串s对应的编号
clr(ok1,0);//ok1[x]表示x是不是A的朋友
for(int i = 0;i < child[u].size(); ++ i)//标记u的所有朋友
ok1[child[u][i]] = true;
ok1[u] = true;
clr(ok2,0);//ok2[x]表示x与A有几个共同朋友
dp = 0;//dp:与A有相同朋友的最大值,且与A并不是朋友
for(int i = 0;i < child[u].size(); ++ i){
int v = child[u][i];
for(int j = 0;j < child[v].size(); ++ j){
int x = child[v][j];
if(ok1[x]) continue;//如果与A是朋友,没有意思,不必处理
ok2[x] ++ ;
dp = max(dp,ok2[x]) ;
}
}
bool ok = true;//控制输出格式
for(it = mp.begin();it != mp.end(); ++ it)//map容器本身就字典序排好了
if(ok1[it->second]==false&&ok2[it->second]==dp&&ok2[it->second]) {
if(ok) {cout<<it->first;ok = false;}
else cout<<" "<<it->first;
}
if(!ok) {puts("");return true;}
return false;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
#endif // ONLINE_JUDGE
int T;cin>>T;int cnt = 1;
while(T--){
scanf("%d%d",&n,&Q);
mp.clear();
for(int i = 1; i <= 2*n; ++ i) child[i].clear();//初始化
int top = 1;
for(int i = 0;i < n; ++ i){
cin>>s1>>s2;
if(!mp[s1]) mp[s1] = top++;
if(!mp[s2]) mp[s2] = top++;//字符串作map映射
child[mp[s1]].push_back(mp[s2]);
child[mp[s2]].push_back(mp[s1]);//无向图建立
}
printf("Case %d:\n",cnt++);
for(int i = 0; i < Q; ++ i){
cin>>s1;
if(!query(s1)) puts("-");
}
}
return 0;
}
- 加粗
Ctrl + B
- 斜体
Ctrl + I
- 引用
Ctrl + Q
- 插入链接
Ctrl + L
- 插入代码
Ctrl + K
- 插入图片
Ctrl + G
- 提升标题
Ctrl + H
- 有序列表
Ctrl + O
- 无序列表
Ctrl + U
- 横线
Ctrl + R
- 撤销
Ctrl + Z
- 重做
Ctrl + Y