codevs 2370 小机房的树
题目链接:http://codevs.cn/problem/2370/
题解:
裸LCA,注意结点是从0开始编号
Tarjan
1 #include<cstdio> 2 #define MAXN 50010 3 #define MAXQ 75010 4 int n,Q,heade[MAXN],headq[MAXN],fa[MAXN],lca[MAXQ],dis[MAXN],cnt; 5 bool vis[MAXN]; 6 struct edge 7 { 8 int v,next,val; 9 }e[MAXN*2]; 10 struct query 11 { 12 int u,v,next; 13 }q[MAXQ*2]; 14 void adde(int x,int y,int z) 15 { 16 e[++cnt].v=y; 17 e[cnt].next=heade[x]; 18 heade[x]=cnt; 19 e[cnt].val=z; 20 } 21 void addq(int x,int y) 22 { 23 q[++cnt].u=x; 24 q[cnt].v=y; 25 q[cnt].next=headq[x]; 26 headq[x]=cnt; 27 } 28 int getfa(int x) 29 { 30 return fa[x]=x==fa[x]?x:getfa(fa[x]); 31 } 32 int getdis(int i) 33 { 34 return dis[q[i<<1].u]+dis[q[i<<1].v]-2*dis[lca[i]]; 35 } 36 void Tarjan(int u) 37 { 38 fa[u]=u; 39 vis[u]=true; 40 for(int i=heade[u];i;i=e[i].next) 41 { 42 int v=e[i].v; 43 if(!vis[v]) 44 { 45 dis[v]=dis[u]+e[i].val; 46 Tarjan(v); 47 fa[v]=u; 48 } 49 } 50 for(int i=headq[u];i;i=q[i].next) 51 { 52 int v=q[i].u==u?q[i].v:q[i].u; 53 if(vis[v])lca[i>>1]=getfa(fa[v]); 54 } 55 } 56 int main() 57 { 58 scanf("%d",&n); 59 int x,y,z; 60 for(int i=1;i<n;i++) 61 { 62 scanf("%d%d%d",&x,&y,&z); 63 ++x;++y; 64 adde(x,y,z); 65 adde(y,x,z); 66 } 67 cnt=1; 68 scanf("%d",&Q); 69 for(int i=1;i<=Q;i++) 70 { 71 scanf("%d%d",&x,&y); 72 ++x;++y; 73 addq(x,y); 74 addq(y,x); 75 } 76 Tarjan(1); 77 for(int i=1;i<=Q;i++) 78 { 79 printf("%d\n",getdis(i)); 80 } 81 return 0; 82 }
树上倍增
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 struct edge 5 { 6 int v,next,val; 7 }e[100005]; 8 int n,m,heads[50005],q[50005],head,tail,fa[17][50005],dis[50005],dep[50005],cnt; 9 void add(int u,int v,int val) 10 { 11 e[++cnt].next=heads[u]; 12 heads[u]=cnt; 13 e[cnt].v=v; 14 e[cnt].val=val; 15 } 16 int dfs(int u) 17 { 18 for(int i=heads[u];i;i=e[i].next) 19 { 20 if(e[i].v!=fa[0][u]) 21 { 22 dep[e[i].v]=dep[u]+1; 23 fa[0][e[i].v]=u; 24 dis[e[i].v]=dis[u]+e[i].val; 25 dfs(e[i].v); 26 } 27 } 28 } 29 int LCA(int u,int v) 30 { 31 if(dep[u]>dep[v])swap(u,v); 32 for(int i=16;~i;i--) 33 if(dep[fa[i][v]]>=dep[u]) 34 v=fa[i][v]; 35 if(u==v)return u; 36 for(int i=16;~i;i--) 37 if(fa[i][u]!=fa[i][v]) 38 { 39 u=fa[i][u]; 40 v=fa[i][v]; 41 } 42 return fa[0][u]; 43 } 44 int main() 45 { 46 scanf("%d",&n); 47 for(int i=1;i<n;i++) 48 { 49 int x,y,z; 50 x++;y++; 51 scanf("%d%d%d",&x,&y,&z); 52 add(x,y,z); 53 add(y,x,z); 54 } 55 dep[1]=fa[0][1]=1; 56 dfs(1); 57 for(int i=1;i<=16;i++) 58 for(int j=1;j<=n;j++) 59 fa[i][j]=fa[i-1][fa[i-1][j]]; 60 scanf("%d",&m); 61 while(m--) 62 { 63 int x,y; 64 x++;y++; 65 scanf("%d%d",&x,&y); 66 printf("%d\n",dis[x]+dis[y]-2*dis[LCA(x,y)]); 67 } 68 return 0; 69 }