lca 最近公共祖先
http://poj.org/problem?id=1330
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int inf=0x3f3f3f3f; 7 class LCA { ///最近公共祖先 build_o(n*logn) query_o(1) 8 typedef int typec;///边权的类型 9 static const int ME=2e4+10;///边的个数 10 static const int MV=1e4+10;///点的个数 11 static const int MR=MV<<1;///rmq的个数 12 struct E { 13 int v,next; 14 typec w; 15 } e[ME]; 16 int le,head[MV],H[MV],dex[MR],aa[MR],bb[MR],raa[MR][20],rbb[MR][20],Index; 17 typec dist[MV]; 18 void init_dex() { 19 dex[0]=-1; 20 for(int i=1; i<MR; i++) { 21 dex[i]=dex[i>>1]+1; 22 } 23 } 24 void dfs(int u,int fa,int level) { 25 aa[Index]=u; 26 bb[Index++]=level; 27 for(int i=head[u]; ~i; i=e[i].next) { 28 int v=e[i].v; 29 if(v==fa) continue; 30 dist[v]=dist[u]+e[i].w; 31 dfs(v,u,level+1); 32 aa[Index]=u; 33 bb[Index++]=level; 34 } 35 } 36 public: 37 LCA() { init_dex();}; 38 void init() { 39 le=Index=0; 40 mt(head,-1); 41 } 42 void add(int u,int v,typec w) { 43 e[le].v=v; 44 e[le].w=w; 45 e[le].next=head[u]; 46 head[u]=le++; 47 } 48 void build(int root) { 49 dist[root]=0; 50 dfs(root,-1,0); 51 mt(H,-1); 52 mt(rbb,0x3f); 53 for(int i=0; i<Index; i++) { 54 int tmp=aa[i]; 55 if(H[tmp]==-1) H[tmp]=i; 56 rbb[i][0]=bb[i]; 57 raa[i][0]=aa[i]; 58 } 59 for(int i=1; (1<<i)<=Index; i++) { 60 for(int j=0; j+(1<<i)<Index; j++) { 61 int next=j+(1<<(i-1)); 62 if(rbb[j][i-1]<=rbb[next][i-1]) { 63 rbb[j][i]=rbb[j][i-1]; 64 raa[j][i]=raa[j][i-1]; 65 } else { 66 rbb[j][i]=rbb[next][i-1]; 67 raa[j][i]=raa[next][i-1]; 68 } 69 } 70 } 71 } 72 int query(int l,int r) { 73 l=H[l]; 74 r=H[r]; 75 if(l>r) swap(l,r); 76 int p=dex[r-l+1]; 77 r-=(1<<p)-1; 78 return rbb[l][p]<=rbb[r][p]?raa[l][p]:raa[r][p]; 79 } 80 typec getdist(int l,int r) { 81 return dist[l]+dist[r]-2*dist[query(l,r)]; 82 } 83 } gx; 84 85 const int M=1e4+10; 86 int du[M]; 87 int main() { 88 int t,n,u,v; 89 while(~scanf("%d",&t)) { 90 while(t--) { 91 scanf("%d",&n); 92 gx.init(); 93 mt(du,0); 94 for(int i=1; i<n; i++) { 95 scanf("%d%d",&u,&v); 96 du[v]++; 97 gx.add(u,v,1); 98 gx.add(v,u,1); 99 } 100 int rt=1; 101 for(int i=1; i<=n; i++) { 102 if(du[i]==0) { 103 rt=i; 104 break; 105 } 106 } 107 gx.build(rt); 108 scanf("%d%d",&u,&v); 109 printf("%d\n",gx.query(u,v)); 110 } 111 } 112 return 0; 113 }
http://poj.org/problem?id=1470
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<cctype> 4 #include<algorithm> 5 #define mt(a,b) memset(a,b,sizeof(a)) 6 using namespace std; 7 int getint(){ 8 int res=0; 9 char tmp; 10 while(!isdigit(tmp=getchar())); 11 do{ 12 res=(res<<3)+(res<<1)+tmp-'0'; 13 }while(isdigit(tmp=getchar())); 14 return res; 15 } 16 17 class LCA { ///最近公共祖先 build_o(n*logn) query_o(1) 18 typedef int typec;///边权的类型 19 static const int ME=2e3+10;///边的个数 20 static const int MV=1e3+10;///点的个数 21 static const int MR=MV<<1;///rmq的个数 22 struct E { 23 int v,next; 24 typec w; 25 } e[ME]; 26 int le,head[MV],H[MV],dex[MR],aa[MR],bb[MR],raa[MR][20],rbb[MR][20],Index; 27 typec dist[MV]; 28 void init_dex() { 29 dex[0]=-1; 30 for(int i=1; i<MR; i++) { 31 dex[i]=dex[i>>1]+1; 32 } 33 } 34 void dfs(int u,int fa,int level) { 35 aa[Index]=u; 36 bb[Index++]=level; 37 for(int i=head[u]; ~i; i=e[i].next) { 38 int v=e[i].v; 39 if(v==fa) continue; 40 dist[v]=dist[u]+e[i].w; 41 dfs(v,u,level+1); 42 aa[Index]=u; 43 bb[Index++]=level; 44 } 45 } 46 public: 47 LCA() { 48 init_dex(); 49 }; 50 void init() { 51 le=Index=0; 52 mt(head,-1); 53 } 54 void add(int u,int v,typec w) { 55 e[le].v=v; 56 e[le].w=w; 57 e[le].next=head[u]; 58 head[u]=le++; 59 } 60 void build(int root) {///传入树根 61 dist[root]=0; 62 dfs(root,-1,0); 63 mt(H,-1); 64 mt(rbb,0x3f); 65 for(int i=0; i<Index; i++) { 66 int tmp=aa[i]; 67 if(H[tmp]==-1) H[tmp]=i; 68 rbb[i][0]=bb[i]; 69 raa[i][0]=aa[i]; 70 } 71 for(int i=1; (1<<i)<=Index; i++) { 72 for(int j=0; j+(1<<i)<Index; j++) { 73 int next=j+(1<<(i-1)); 74 if(rbb[j][i-1]<=rbb[next][i-1]) { 75 rbb[j][i]=rbb[j][i-1]; 76 raa[j][i]=raa[j][i-1]; 77 } else { 78 rbb[j][i]=rbb[next][i-1]; 79 raa[j][i]=raa[next][i-1]; 80 } 81 } 82 } 83 } 84 int query(int l,int r) {///查lca 85 l=H[l]; 86 r=H[r]; 87 if(l>r) swap(l,r); 88 int p=dex[r-l+1]; 89 r-=(1<<p)-1; 90 return rbb[l][p]<=rbb[r][p]?raa[l][p]:raa[r][p]; 91 } 92 typec getdist(int l,int r) {///查两点最短距离 93 return dist[l]+dist[r]-2*dist[query(l,r)]; 94 } 95 } g; 96 97 int ans[1024]; 98 int du[1024]; 99 int main(){ 100 int n,m,u,v; 101 while(~scanf("%d",&n)){ 102 g.init(); 103 mt(du,0); 104 for(int i=0;i<n;i++){ 105 u=getint(); 106 m=getint(); 107 while(m--){ 108 v=getint(); 109 du[v]++; 110 g.add(u,v,1); 111 g.add(v,u,1); 112 } 113 } 114 int root=1; 115 for(int i=2;i<=n;i++){ 116 if(du[i]==0){ 117 root=i; 118 break; 119 } 120 } 121 g.build(root); 122 m=getint(); 123 mt(ans,0); 124 // printf("m=%d\n",m); 125 for(int i=0;i<m;i++){ 126 u=getint(); 127 v=getint(); 128 // printf("u=%d v=%d\n",u,v); 129 ans[g.query(u,v)]++; 130 // printf("m=%d\n",m); 131 } 132 // puts("out"); 133 for(int i=1;i<=n;i++){ 134 if(ans[i]){ 135 printf("%d:%d\n",i,ans[i]); 136 } 137 } 138 139 } 140 return 0; 141 }
http://poj.org/problem?id=1986
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int inf=0x3f3f3f3f; 7 //const int M=100010; 8 class LCA { ///最近公共祖先 build_o(n*logn) query_o(1) 9 typedef int typec;///边权的类型 10 static const int ME=2e5+10;///边的个数 11 static const int MV=1e5+10;///点的个数 12 static const int MR=MV<<1;///rmq的个数 13 struct E { 14 int v,next; 15 typec w; 16 } e[ME]; 17 int le,head[MV],H[MV],dex[MR],aa[MR],bb[MR],raa[MR][20],rbb[MR][20],Index; 18 typec dist[MV]; 19 void init_dex() { 20 dex[0]=-1; 21 for(int i=1; i<MR; i++) { 22 dex[i]=dex[i>>1]+1; 23 } 24 } 25 void dfs(int u,int fa,int level) { 26 aa[Index]=u; 27 bb[Index++]=level; 28 for(int i=head[u]; ~i; i=e[i].next) { 29 int v=e[i].v; 30 if(v==fa) continue; 31 dist[v]=dist[u]+e[i].w; 32 dfs(v,u,level+1); 33 aa[Index]=u; 34 bb[Index++]=level; 35 } 36 } 37 public: 38 LCA() { 39 init_dex(); 40 }; 41 void init() { 42 le=Index=0; 43 mt(head,-1); 44 } 45 void add(int u,int v,typec w) { 46 e[le].v=v; 47 e[le].w=w; 48 e[le].next=head[u]; 49 head[u]=le++; 50 } 51 void build(int root) {///传入树根 52 dist[root]=0; 53 dfs(root,-1,0); 54 mt(H,-1); 55 mt(rbb,0x3f); 56 for(int i=0; i<Index; i++) { 57 int tmp=aa[i]; 58 if(H[tmp]==-1) H[tmp]=i; 59 rbb[i][0]=bb[i]; 60 raa[i][0]=aa[i]; 61 } 62 for(int i=1; (1<<i)<=Index; i++) { 63 for(int j=0; j+(1<<i)<Index; j++) { 64 int next=j+(1<<(i-1)); 65 if(rbb[j][i-1]<=rbb[next][i-1]) { 66 rbb[j][i]=rbb[j][i-1]; 67 raa[j][i]=raa[j][i-1]; 68 } else { 69 rbb[j][i]=rbb[next][i-1]; 70 raa[j][i]=raa[next][i-1]; 71 } 72 } 73 } 74 } 75 int query(int l,int r) {///查lca 76 l=H[l]; 77 r=H[r]; 78 if(l>r) swap(l,r); 79 int p=dex[r-l+1]; 80 r-=(1<<p)-1; 81 return rbb[l][p]<=rbb[r][p]?raa[l][p]:raa[r][p]; 82 } 83 typec getdist(int l,int r) {///查两点最短距离 84 return dist[l]+dist[r]-2*dist[query(l,r)]; 85 } 86 } gx; 87 88 #include<cctype> 89 int getint(){ 90 int res=0; 91 char tmp; 92 while(!isdigit(tmp=getchar())); 93 do{ 94 res=(res<<3)+(res<<1)+tmp-'0'; 95 }while(isdigit(tmp=getchar())); 96 return res; 97 } 98 int main(){ 99 int n,m,x,y,z; 100 char op[4]; 101 while(~scanf("%d%d",&n,&m)){ 102 gx.init(); 103 while(m--){ 104 // scanf("%d%d%d%s",&x,&y,&z,op); 105 x=getint(); 106 y=getint(); 107 z=getint(); 108 gx.add(x,y,z); 109 gx.add(y,x,z); 110 } 111 // scanf("%d",&m); 112 m=getint(); 113 gx.build(1); 114 while(m--){ 115 // scanf("%d%d",&x,&y); 116 x=getint(); 117 y=getint(); 118 printf("%d\n",gx.getdist(x,y)); 119 } 120 } 121 return 0; 122 }
end