思路:
使用tarjan算法,这是一种离线算法。
实现:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef pair<int, int> pii; 4 const int MAXN = 100005; 5 vector<int> G[MAXN], qry[MAXN]; 6 int par[MAXN], vis[MAXN]; 7 void init(int n) 8 { 9 for (int i = 0; i <= n; i++) par[i] = i; 10 } 11 int find(int x) 12 { 13 if (par[x] == x) return par[x]; 14 return par[x] = find(par[x]); 15 } 16 int uni(int x, int y) 17 { 18 x = find(x); y = find(y); 19 if (x == y) return x; 20 par[x] = y; return y; 21 } 22 void dfs(int u, int f, map<pii, int> & ans) 23 { 24 vis[u] = 1; 25 for (auto it: qry[u]) 26 { 27 int tmp = vis[it]; 28 if (!tmp) continue; 29 if (tmp == 1) 30 ans[pii(u, it)] = it; 31 else if (tmp == 2) 32 ans[pii(u, it)] = find(it); 33 } 34 for (int i = 0; i < G[u].size(); i++) 35 if (!vis[G[u][i]]) dfs(G[u][i], u, ans); 36 vis[u] = 2; 37 uni(u, f); 38 } 39 int main() 40 { 41 int n, q; 42 cin >> n; 43 string x, y; 44 map<string, int> mp; 45 map<int, string> mp2; 46 int id = 1, root = -1; 47 for (int i = 0; i < n; i++) 48 { 49 cin >> x >> y; 50 int pid = -1, sid = -1; 51 if (!mp.count(x)) { mp[x] = pid = id; mp2[id] = x; id++; } 52 else pid = mp[x]; 53 if (!mp.count(y)) { mp[y] = sid = id; mp2[id] = y; id++; } 54 else sid = mp[y]; 55 if (i == 0) root = pid; 56 G[pid].push_back(sid); 57 } 58 cin >> q; 59 vector<pii> v; 60 for (int i = 0; i < q; i++) 61 { 62 cin >> x >> y; 63 int xid = mp[x], yid = mp[y]; 64 qry[xid].push_back(yid); 65 qry[yid].push_back(xid); 66 v.push_back(pii(xid, yid)); 67 } 68 init(n); 69 map<pii, int> ans; 70 dfs(root, 0, ans); 71 for (auto it: v) 72 { 73 int xid = it.first, yid = it.second; 74 pii a(xid, yid), b(yid, xid); 75 if (ans.count(a)) cout << mp2[ans[a]] << endl; 76 else cout << mp2[ans[b]] << endl; 77 } 78 return 0; 79 }