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 }