1 /*
2 题意:最近公共祖先
3 题解:tarjan算法实现
4 时间:2018.07.18
5 */
6
7 #include <bits/stdc++.h>
8 using namespace std;
9
10 typedef long long LL;
11 const int MAXN = 100005;
12 const LL MOD7 = 1e9+7;
13
14 struct Edge
15 {
16 int u,v;
17 int next;
18 }edge[4*MAXN];
19 int head[MAXN];
20 int cnt;
21
22 struct Query
23 {
24 int u,v;
25 int ans;
26 int idx;
27 }Qe[MAXN];
28 vector<int> g[MAXN];
29
30 int f[MAXN];
31 int vis[MAXN];
32
33 map<string,int> names;
34 map<int,string> ids;
35 int K;
36
37 int n,Q;
38
39 void init()
40 {
41 cnt=0;
42 memset(head,-1,sizeof(head));
43 }
44
45 void addEdge(int u,int v)
46 {
47 edge[cnt].u=u;edge[cnt].v=v;edge[cnt].next=head[u];head[u]=cnt++;
48 }
49
50 int Find(int x)
51 {
52 if (x==f[x]) return x;
53 return f[x]=Find(f[x]);
54 }
55
56 void union_set(int x,int y)
57 {
58 int fx=Find(x);
59 int fy=Find(y);
60 if (fx!=fy)
61 f[fx]=fy;
62 }
63
64 void tarjan(int u)
65 {
66 vis[u]=1;
67 for (int i=head[u];i!=-1;i=edge[i].next)
68 {
69 int v=edge[i].v;
70 if (!vis[v])
71 {
72 tarjan(v);
73 union_set(v,u);
74 }
75 }
76 for (int i:g[u])
77 {
78 int v = Qe[i].v;
79 if (v==u) v=Qe[i].u;
80 if (vis[v]) Qe[i].ans = Find(v);
81 }
82 }
83
84 int main()
85 {
86 #ifndef ONLINE_JUDGE
87 freopen("test.txt","r",stdin);
88 #endif // ONLINE_JUDGE
89 scanf("%d",&n);
90 init();
91 K=0;
92 string s1,s2;
93 int u,v;
94 int root=-1;
95 for (int i=1;i<=n;++i)
96 {
97 cin>>s1>>s2;
98 if (names.find(s1)==names.end()){names[s1]=++K;ids[K]=s1;}
99 if (names.find(s2)==names.end()){names[s2]=++K;ids[K]=s2;}
100 u=names[s1];v=names[s2];
101 addEdge(u,v);
102 addEdge(v,u);
103 if (root==-1 || v==root) root=u;
104 }
105 for (int i=0;i<=K;++i) f[i]=i;
106 scanf("%d",&Q);
107 for (int i=1;i<=Q;++i)
108 {
109 cin>>s1>>s2;
110 u=names[s1];v=names[s2];
111 Qe[i].u=u;Qe[i].v=v;Qe[i].idx=i;Qe[i].ans=-1;
112 g[u].push_back(i);g[v].push_back(i);
113 }
114 memset(vis,0,sizeof(vis));
115 tarjan(root);
116 for (int i=1;i<=Q;++i)
117 {
118 cout<<ids[Qe[i].ans]<<endl;
119 }
120 return 0;
121 }
1 /*
2 题意:最近公共祖先
3 题解:dfs + RMQ_ST实现
4 时间:2018.07.18
5 */
6
7 #include <bits/stdc++.h>
8 using namespace std;
9
10 typedef long long LL;
11 const int MAXN = 100005;
12 const LL MOD7 = 1e9+7;
13
14 struct Edge
15 {
16 int u,v;
17 int next;
18 }edge[4*MAXN];
19 int head[MAXN];
20 int cnt;
21
22 map<string,int> names;
23 map<int,string> ids;
24 int K;
25 int n,Q;
26
27
28 void init()
29 {
30 cnt=0;
31 memset(head,-1,sizeof(head));
32 }
33
34 void addEdge(int u,int v)
35 {
36 edge[cnt].u=u;edge[cnt].v=v;edge[cnt].next=head[u];head[u]=cnt++;
37 }
38
39 struct RMQ_ST
40 {
41 int a[2*MAXN];
42 int dp[MAXN][30];
43 int n;
44 void init(int n, int a[])
45 {
46 this->n = n;
47 for (int i=1;i<=n;++i) this->a[i] = a[i];
48 for (int i=1;i<=n;++i) dp[i][0] = i;
49 for (int j=1;(1<<j)<=n;++j)
50 {
51 for (int i=1;i+(1<<j)-1<=n;++i)
52 {
53 dp[i][j] = (a[dp[i][j-1]]<a[dp[i+(1<<(j-1))][j-1]]?dp[i][j-1]:dp[i+(1<<(j-1))][j-1]);
54 }
55 }
56 }
57 int query(int x,int y)
58 {
59 if (x>y) swap(x,y);
60 int j = log(y-x+1)/log(2);
61 return (a[dp[x][j]]<a[dp[y-(1<<j)+1][j]]?dp[x][j]:dp[y-(1<<j)+1][j]);
62 }
63 }st;
64
65 int ss[MAXN]; // 第一次访问节点的时间
66 int F[2*MAXN]; // 时间对应的节点
67 int depth[2*MAXN]; //每个时间对应的深度
68 int tot;
69
70 void dfs(int u,int pre,int dep)
71 {
72 F[++tot]=u;
73 depth[tot]=dep;
74 ss[u]=tot;
75 for (int i=head[u];i!=-1;i=edge[i].next)
76 {
77 int v=edge[i].v;
78 if (v==pre) continue;
79 dfs(v,u,dep+1);
80 F[++tot]=u;
81 depth[tot]=dep;
82 }
83 }
84
85 int main()
86 {
87 #ifndef ONLINE_JUDGE
88 freopen("test.txt","r",stdin);
89 #endif // ONLINE_JUDGE
90 scanf("%d",&n);
91 init();
92 K=0;
93 string s1,s2;
94 int u,v;
95 int root=-1;
96 for (int i=1;i<=n;++i)
97 {
98 cin>>s1>>s2;
99 if (names.find(s1)==names.end()){names[s1]=++K;ids[K]=s1;}
100 if (names.find(s2)==names.end()){names[s2]=++K;ids[K]=s2;}
101 u=names[s1];v=names[s2];
102 addEdge(u,v);
103 addEdge(v,u);
104 if (root==-1 || v==root) root=u;
105 }
106 tot=0;
107 dfs(root,-1,0);
108 st.init(tot,depth);
109 scanf("%d",&Q);
110 for (int i=1;i<=Q;++i)
111 {
112 cin>>s1>>s2;
113 u=names[s1];v=names[s2];
114 int t = F[st.query(ss[u],ss[v])];
115 cout<<ids[t]<<endl;
116 }
117 return 0;
118 }