题目大意:
一张人际关系网络图,然后给出一对情侣A和B(负数代表女生,正数代表男生),要求找到A的朋友(不是B,和A性别相同)C,B的朋友(不是A,和B的性别相同)D,如果C和D是朋友那么输出C和D的编号(输出的编号均为正数),并且按照C的非递减排列,如果相同,则按照D的升序排列。
算法思路:
对于每个人的编号保存其符号进行输入,使用string类型变量接收, 这样,判断性别是否相同直接判断两个字符串长度是否一样就行,并且为了简化搜索,我们用邻接表Adj只保存每一个人的同性朋友,然后再使用邻接矩阵保存所有的朋友关系,其行为男生,列为女生,这样就可以将女生转化为正数来进行保存,又由于题目的特殊性,从A到B的路径一定得是一个长度为4的路径,那么就直接遍历每一个A的同性朋友和B的同性朋友,判断这两人是否是朋友就好。如果是就说明找到了C和D,并将其添加进result中,在遍历结束后,对result按照规则排序输出即可.
注意点:
- 1、此题没有必要使用DFS,第一个原因是男生编号为0000,女生编号为-0000的情况不是很好处理,第二是最后一个测试点会运行超时。
- 2、这里使用邻接表只保存同性朋友可以大大降低时间复杂度。
- 3、对于A的朋友不能是B,对于B的朋友不能是A,这里是针对A和B是同性朋友的特殊处理,防止路径长度为2.
提交结果:
AC代码:
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#include<iostream>
using namespace std;
struct Pair{
int first,second;
Pair(int f,int s){
first = f;
second = s;
}
};
vector<int> Adj[10000];// 邻接表 ,保存每一个人的同性朋友
int G[10000][10000];// 邻接矩阵,用来判断任意2人是否是朋友
bool cmp(const Pair &a,const Pair &b){
return a.first!=b.first?a.first<b.first:a.second<b.second;
}
int main(){
int N,M;
scanf("%d %d",&N,&M);
string a,b;
for(int i=0;i<M;++i){
cin>>a>>b;
int A = abs(stoi(a));
int B = abs(stoi(b));
if(a.size()==b.size()){
// a和b是同性朋友
Adj[A].push_back(B);
Adj[B].push_back(A);
}
G[A][B] = G[B][A] = 1;
}
int K;
scanf("%d",&K);
for(int i=0;i<K;++i){
vector<Pair> result;
cin>>a>>b;
int A = abs(stoi(a));
int B = abs(stoi(b));
// 遍历A的同性朋友
for(auto &friendA:Adj[A]){
// 遍历B的同性朋友
if(friendA==B) continue;// 其朋友不能是B,不然长度不能到达4
for(auto &friendB:Adj[B]){
if(friendB==A) continue;// 其朋友不能是A,不然长度不能到达4
if(G[friendA][friendB]==1){
// 找到C和D
result.emplace_back(friendA,friendB);
}
}
}
if(result.empty()){
printf("0\n");
}else {
printf("%lu\n",result.size());
sort(result.begin(),result.end(),cmp);
for(auto &item:result){
printf("%04d %04d\n",item.first,item.second);
}
}
}
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。