题目链接:点击打开链接
题目大意:略。
解题思路:
- 用数组vis标记两个人是否是朋友(邻接矩阵表示),用vec标记所有人的同性朋友(邻接表表示)unordered_map<int, int> vis 替代二维数组可避免内存超限。
- 对于一对想要在一起的A和B,他们需要先找A的所有同性朋友C,再找B的所有同性朋友D,当C和D两人是朋友的时候则可以输出C和D。
- A在寻找同性朋友时,需要避免找到他想要的伴侣B,所以当当前朋友就是B或者B的同性朋友就是A时舍弃该结果。
- 如果用int接收一对朋友,-0000和0000对于int来说都是0,将无法得知这个人的性别,也就会影响他找他的同性朋友的那个步骤,所以考虑用字符串接收,因为题目中已经表示会以符号位加四位的方式给出输入,所以只要判断字符串是否大小相等,如果大小相等说明这两个人是同性。
- 结果数组因为必须按照第一个人的编号从小到大排序(当第一个相等时按照第二个人编号的从小到大排序),所以要用sort对ps数组排序后再输出结果。
AC 代码
usingnamespacestd; typedeflonglongll; constintmaxn=1e4+10; structpeo{ intu,v; }ps[maxn*10]; unordered_map<int,int>vis; vector<int>vec[maxn]; intfhash(intid1,intid2) { returnid1*10000+id2; } intcmp(peop1, peop2) { returnp1.u==p2.u?p1.v<p2.v : p1.u<p2.u; } intmain() { intn,m,u,v,q; strings1,s2; stringstreamss; scanf("%d%d",&n,&m); for(inti=0;i<m;i++) { cin>>s1>>s2; ssclr(ss), ss<<s1, ss>>u; ssclr(ss), ss<<s2, ss>>v; u=abs(u), v=abs(v); if(s1.length()==s2.length()) { vec[u].push_back(v); vec[v].push_back(u); } vis[fhash(u,v)]=vis[fhash(v,u)]=1; } scanf("%d",&q); while(q--) { intl=0; scanf("%d%d",&u,&v); u=abs(u), v=abs(v); for(inti=0;i<vec[u].size();i++) { for(intj=0;j<vec[v].size();j++) { if(vec[u][i]==v||vec[v][j]==u) continue; if(vis[fhash(vec[u][i],vec[v][j])]==1) ps[l].u=vec[u][i], ps[l++].v=vec[v][j]; } } sort(ps,ps+l,cmp); printf("%d\n",l); for(inti=0;i<l;i++) printf("%04d %04d\n",ps[i].u,ps[i].v); } return0; }