一开始的思路:
从源点开始进行深度不超过3的DFS,深度到达3时判断是否到达终点,到达则记录当前路径。
想得太复杂了,且最后有三个点答案错误,也没有考虑正负零的差别。
一开始的代码:
#include <iostream>
#include <unordered_set>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;
struct Friend{
int first;
int second;
};
vector<int> G[10000];
unordered_set<int> students;
vector<Friend> res;
stack<int> st;
bool cmp(Friend a,Friend b){
if(a.first != b.first)
return abs(a.first) < abs(b.first);
return abs(a.second) < abs(b.second);
}
void DFS(int source,int s,int d,int level){
if(level == 1){ // 要找一个和s一样性别的
if(s < 0){
for(int i = 0;i < G[abs(s)].size();i++){
if(G[abs(s)][i] < 0 && G[abs(s)][i] != source && G[abs(s)][i] != d){
st.push(G[abs(s)][i]);
DFS(source,G[abs(s)][i],d,2);
st.pop();
}
}
}else{
for(int i = 0;i < G[s].size();i++){
if(G[s][i] > 0 && G[s][i] != source && G[s][i] != d){
st.push(G[s][i]);
DFS(source,G[s][i],d,2);
st.pop();
}
}
}
}else if(level == 2){ // 要找一个和d一样性别的
if(d < 0){
for(int i = 0;i < G[abs(s)].size();i++){
if(G[abs(s)][i] < 0 && G[abs(s)][i] != source && G[abs(s)][i] != d){
st.push(G[abs(s)][i]);
DFS(source,G[abs(s)][i],d,3);
st.pop();
}
}
}else{
for(int i = 0;i < G[abs(s)].size();i++){
if(G[abs(s)][i] > 0 && G[abs(s)][i] != source && G[abs(s)][i] != d){
st.push(G[abs(s)][i]);
DFS(source,G[abs(s)][i],d,3);
st.pop();
}
}
}
}else{ // 要找d
for(int i = 0;i < G[abs(s)].size();i++){
if(G[abs(s)][i] == d){ // 找到
Friend temp;
temp.second = st.top();
st.pop();
temp.first = st.top();
st.push(temp.second);
res.push_back(temp);
break;
}
}
}
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i = 0;i < m;i++){
int u,v;
scanf("%d%d",&u,&v);
students.insert(u);
students.insert(v);
G[abs(u)].push_back(v);
G[abs(v)].push_back(u);
}
int k;
scanf("%d",&k);
for(int i = 0;i < k;i++){
int source,destination;
scanf("%d%d",&source,&destination);
res.clear();
DFS(source,source,destination,1);
sort(res.begin(),res.end(),cmp);
printf("%d\n",res.size());
for(int j = 0;j < res.size();j++){
printf("%d %d\n",abs(res[j].first),abs(res[j].second));
}
}
system("pause");
return 0;
}
看了网上其他大神的做法后,决定用一个数组存放某个同学的同性朋友。
对每个A的同性朋友B和D的同性朋友C,判断B和C是否是朋友,是则记录,注意在朋友中去掉A的同性朋友是D和D的同性朋友是A的情况即可。
但依旧有测试点答案错误,暂时还没想到错在哪。待优化
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <sstream>
#include <algorithm>
using namespace std;
struct Friend{
int first;
int second;
Friend(int f,int s){
first = f;
second = s;
}
Friend(){}
};
namespace std{
template <>
struct hash<Friend>{
size_t operator()(Friend const & x) const{
return(51 + std::hash<int>()(x.first) * 51 + std::hash<int>()(x.second));
}
};
}
bool operator==(const struct Friend & X,const struct Friend & Y){
return (hash<int>()(X.first) == hash<int>()(Y.first) && hash<int>()(X.second) == hash<int>()(Y.second));
}
//bool G[10000][10000]; // 两个人是否是朋友
unordered_set<Friend> G;
unordered_map<int,bool> gender;
vector<int> sameGenderFriends[10000]; // 同性朋友
vector<Friend> res;
bool cmp(Friend a,Friend b){
return (a.first == b.first) ? (a.second < b.second) : (a.first < b.first);
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i = 0;i < m;i++){
string a,b;
int u,v;
cin>>a>>b;
stringstream sa,sb;
sa<<a;
sa>>u;
sb<<b;
sb>>v;
u = abs(u);
v = abs(v);
if(a[0] == '-')
gender[u] = false;
else
gender[u] = true;
if(b[0] == '-')
gender[v] = false;
else
gender[v] = true;
G.insert(Friend(u,v));
if(gender[u] == gender[v]){ // 两人同性
sameGenderFriends[u].push_back(v);
sameGenderFriends[v].push_back(u);
}
}
int k;
scanf("%d",&k);
for(int i = 0;i < k;i++){
res.clear();
int source,destination;
scanf("%d%d",&source,&destination);
source = abs(source);
destination = abs(destination);
for(int j = 0;j < sameGenderFriends[source].size();j++){ // 对源点的每一个同性朋友:
if(sameGenderFriends[source][j] == destination)
continue;
for(int p = 0;p < sameGenderFriends[destination].size();p++){ // 对终点的每一个同性朋友:
if(sameGenderFriends[destination][p] == source)
continue;
if(G.find(Friend(sameGenderFriends[source][j],sameGenderFriends[destination][p])) != G.end()
||
G.find(Friend(sameGenderFriends[destination][p],sameGenderFriends[source][j])) != G.end()){
res.push_back(Friend(sameGenderFriends[source][j],sameGenderFriends[destination][p]));
}
}
}
sort(res.begin(),res.end(),cmp);
printf("%d\n",res.size());
for(int j = 0;j < res.size();j++){
printf("%d %d\n",res[j].first,res[j].second);
}
}
system("pause");
return 0;
}