hdu 4034 预处理+map映射字符串

来源:互联网 发布:淘宝美工做什么工作的 编辑:程序博客网 时间:2024/06/16 20:07

首先要注意输出时候有空格的问题,一行的最后一个空格不要输出!!切记!!

我的做法就是前n次,每得到一组关系,即A和B是朋友

就找到A的全部朋友,把B和他们的公共朋友数+1(A)

因为每组关系只出现一次,即对于人C来说,如果他现在不是A的朋友,那么B和C现在不会加

如果现在和A是朋友,那么现在会加一次,而以后不会出现A,C或者AB这个关系了,所以C,B有A这个公共朋友只会加这一次

如果现在C不是A的朋友,那么如果以后有CA,也会更新C和B的关系

这么一来公共朋友数就可以N*N的时间内完成

然后Q次访问每次只要O(N)就可以了(注意如果是朋友则不需要推荐)

然后就是一个排序的事


其实做题的时候我对上面的还没有太想清楚……

不过好巧居然过了

查了网上的方案,可以用字典树做映射,一个字典树的终止节点对应一个名字,在字典树的节点中用cnt编号,这样就可以有字符串logn找到他的编号

然后再设置一个保存字符串的数组,就可以由编号直接到字符串,我用两个map有点偷懒……讲道理一个就行了

#include<cstdio>/*1.用map把人名字和序号对应   2.用gra[i][j]存储i和j的相同人个数  3.进来一个relation a-b,把b到a和有关系的那些人,如果b和那些人没关系就+1 ,把a和b到有关系的那些人都+1  真正做的时候如果发现a和b有关系,显然不用推荐。  复杂度1000*1000log1000 * T 勉强可以吧 */ #include<algorithm>#include<string>#include<algorithm>#include<map>#include<set>#include<cstring>#include<iostream>using namespace std;const int maxn = 1500;map<int,string> m1;map<string,int> m2;bool gra[maxn][maxn];int com[maxn][maxn];map<string,int> ::iterator itor; using namespace std;set<string> s;set<string> ::iterator itors;int main(){    int T;    scanf("%d",&T);    for(int test = 1; test <= T; test++){    int n,q;memset(gra,0,sizeof(gra));    memset(com,0,sizeof(com));    m1.clear();    m2.clear();    scanf("%d %d",&n,&q);    int cnt = 0;for(int i = 1; i <= n; i++){    string s1,s2;    cin >> s1 >> s2;    //cout << s1 << s2;    itor = m2.find(s1);        if (itor == m2.end()){    m2[s1] = cnt;    m1[cnt] = s1;    cnt++;}itor = m2.find(s2);if (itor == m2.end()){m2[s2] = cnt;m1[cnt] = s2;cnt++;}int to = m2[s1];int from = m2[s2];gra[from][to] = 1;gra[to][from] = 1;for(int j = 0; j < cnt; j++)if (j != from){if (gra[j][to]){com[j][from]++;com[from][j]++;}}for(int j = 0; j < cnt; j++)if (j != to){if (gra[j][from]){com[j][to]++;com[to][j]++;}}}s.clear();printf("Case %d:\n",test);for(int i = 0; i < q; i++){//printf("q:\n");s.clear(); string s1;cin >> s1;int ans = 0;int from = m2[s1];for(int j = 0; j < cnt; j++){if (j != from && !gra[from][j] && com[from][j] > ans){ans = com[from][j];}}//printf("ans:\n");if (ans == 0) printf("-\n");else{for(int j = 0; j < cnt; j++){if (j != from && !gra[from][j] && com[from][j] == ans){s.insert(m1[j]);}}    for(itors = s.begin(); itors != s.end(); itors++){if (itors != s.begin()) printf(" ");cout << *itors;}printf("\n");}}}return 0;}

0 0
原创粉丝点击