题意:a要和b和好,首先a要找同性的c,c找d,d和b同性,这样就能和好,输出所有的可能。
思路:找到所有和a同性的人,再找到所有和b同性的人,然后看这两个集合中有哪两个人有联系,当然ab不能直接联系。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <set>
using namespace std;
const int MAX_N = 310;
vector<string> v;
map<string, int> mp;
int get_id(string x) {
if (mp.count(x)) return mp[x];
v.push_back(x);
return mp[x] = v.size()-1;
}
int N, M, Q;
int gen[MAX_N];
char s1[100], s2[100];
vector<int> e[MAX_N][2];
typedef pair<string, string> P;
typedef pair<int, int> pi;
vector<P> ans;
map<pi, bool> mt;
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
scanf("%d %d", &N, &M);
for (int i = 0; i < M; i++) {
scanf("%s %s", s1, s2);
if (s1[0]=='-') {gen[get_id(s1)]=1;}
if (s2[0]=='-') {gen[get_id(s2)]=1;}
int id1 = get_id(s1), id2 = get_id(s2);
e[id1][gen[id1]!=gen[id2]].push_back(id2);
e[id2][gen[id1]!=gen[id2]].push_back(id1);
mt[make_pair(id1, id2)] = 1;
mt[make_pair(id2, id1)] = 1;
}
scanf("%d", &Q);
while (Q--) {
ans.clear();
scanf("%s %s", s1, s2);
int id1 = get_id(s1), id2 = get_id(s2);
vector<int> v1, v2;
for (int i = 0; i < e[id2][0].size(); i++) {
if (e[id2][0][i] == id1) continue;
v2.push_back(e[id2][0][i]);
}
for (int i = 0; i < e[id1][0].size(); i++) {
if (e[id1][0][i] == id2) continue;
v1.push_back(e[id1][0][i]);
}
for (int i = 0; i < v1.size(); i++) {
for (int j = 0; j < v2.size(); j++) {
if (mt[make_pair(v1[i], v2[j])]) {
string ss = v[v1[i]], sq = v[v2[j]];
if (ss[0]=='-') ss=ss.substr(1);
if (sq[0]=='-') sq=sq.substr(1);
ans.push_back(make_pair(ss, sq));
}
}
}
sort(ans.begin(), ans.end());
printf("%lu\n", ans.size());
for (int i = 0; i < ans.size(); i++) {
string ss = ans[i].first, sq = ans[i].second;
printf("%s %s\n", ss.c_str(), sq.c_str());
}
}
return 0;
}