LCA模板题,用的方法是转化为RMQ问题来求解,各种WA,折腾了一整天,哎~~~
1 #include <iostream> 2 #include <cstdio> 3 #include <string> 4 #include <cstring> 5 #include <map> 6 #include <vector> 7 using namespace std; 8 const int maxn=100000+100; 9 int pos[maxn],se[maxn*2],d[2*maxn][20]; 10 int e[maxn],head[ maxn],next[maxn],vis[maxn]; 11 map<string,int> a; 12 int n,m,tot2,tot3; 13 void addE(int u,int v) 14 { 15 e[tot2]=v; 16 next[tot2]=head[u]; 17 head[u]=tot2++; 18 } 19 void dfs(int x,int dep) 20 { 21 int i; 22 se[tot3]=dep; 23 pos[x]=tot3++; 24 for(i=head[x];i!=-1;i=next[i]) 25 { 26 dfs(e[i],dep+1); 27 se[tot3++]=dep; 28 } 29 } 30 void ST() 31 { 32 int i,j,k; 33 for(i=0;i<(2*n-1);i++) d[i][0]=se[i]; 34 for(i=1,j=2;j<=(2*n-1);i++,j=j<<1) 35 { 36 for(k=0;(k+j-1)<(2*n-1);k++) 37 d[k][i]=min(d[k][i-1],d[k+(1<<(i-1))][i-1]); 38 } 39 } 40 int main() 41 { 42 int T; 43 cin>>T; 44 while(T--) 45 { 46 scanf("%d%d",&n,&m); 47 a.clear(); 48 int i,j; 49 string s1,s2; 50 int tot=0; 51 tot2=0;tot3=0; 52 memset(head,-1,sizeof(head)); 53 memset(vis,0,sizeof(vis)); 54 int v1,v2; 55 for(i=0;i<n-1;i++) 56 { 57 cin>>s1>>s2; 58 if(!a.count(s1)) a[s1]=tot++; 59 if(!a.count(s2)) a[s2]=tot++; 60 v1=a[s1]; 61 v2=a[s2]; 62 vis[v1]=1; 63 addE(v2,v1); 64 } 65 for(i=0;i<tot;i++) if(!vis[i]) break; 66 dfs(i,0); 67 ST(); 68 int ans,lc1,lc2,t1,t2; 69 for(i=0;i<m;i++) 70 { 71 cin>>s1>>s2; 72 if(n==1) 73 { 74 cout<<0<<endl; 75 continue; 76 } 77 lc1=a[s1];lc2=a[s2]; 78 t1=min(pos[lc1],pos[lc2]); 79 t2=max(pos[lc1],pos[lc2]); 80 j=0; 81 while((1<<j)<=(t2-t1+1)) j++; 82 ans=min(d[t1][j-1],d[t2+1-(1<<(j-1))][j-1]); 83 if(lc1==lc2) ans=0; 84 else if(se[pos[lc1]]==ans) ans=1; 85 else if(se[pos[lc2]]==ans) ans=se[pos[lc1]]-ans; 86 else ans=se[pos[lc1]]-ans+1; 87 cout<<ans<<endl; 88 } 89 } 90 return 0; 91 }