CODEVS 2370 小机房的树
https://www.cnblogs.com/violet-acmer/p/9686774.html
AC代码:
Tarjan+LCA:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 #define pb(x) push_back(x) 7 const int maxn=5e4+50; 8 9 int n,q; 10 int fa[maxn]; 11 int dist[maxn]; 12 bool vis[maxn]; 13 int res[75050]; 14 struct Node 15 { 16 int to; 17 int weight; 18 Node(int to,int weight):to(to),weight(weight){} 19 }; 20 vector<Node >edge[maxn],query[maxn]; 21 void addEdge(int u,int v,int w) 22 { 23 edge[u].pb(Node(v,w)); 24 edge[v].pb(Node(u,w)); 25 } 26 void addQuqry(int u,int v,int id) 27 { 28 query[u].pb(Node(v,id)); 29 query[v].pb(Node(u,id)); 30 } 31 32 //===========LCA================ 33 int Find(int x) 34 { 35 return x == fa[x] ? x:fa[x]=Find(fa[x]); 36 } 37 void Dfs(int v,int f,int l) 38 { 39 fa[v]=v; 40 dist[v]=l; 41 vis[v]=true; 42 for(int i=0;i < edge[v].size();i++) 43 { 44 int to=edge[v][i].to; 45 int w=edge[v][i].weight; 46 if(to != f) 47 { 48 Dfs(to,v,l+w); 49 fa[to]=v; 50 } 51 } 52 for(int i=0;i < query[v].size();i++) 53 { 54 int to=query[v][i].to; 55 int id=query[v][i].weight; 56 if(vis[to]) 57 res[id]=dist[to]-dist[Find(to)]+dist[v]-dist[Find(to)]; 58 } 59 } 60 void Tarjan() 61 { 62 for(int i=1;i <= n;++i) 63 if(!vis[i]) 64 Dfs(i,i,0); 65 } 66 //============================== 67 //============================== 68 void Init() 69 { 70 memset(vis,false,sizeof vis); 71 memset(res,-1,sizeof res); 72 for(int i=1;i <= n;++i) 73 edge[i].clear(),query[i].clear(); 74 } 75 int main() 76 { 77 Init(); 78 scanf("%d",&n); 79 for(int i=1;i < n;++i) 80 { 81 int u,v,w; 82 scanf("%d%d%d",&u,&v,&w); 83 addEdge(u,v,w); 84 } 85 scanf("%d",&q); 86 for(int i=1;i <= q;++i) 87 { 88 int u,v; 89 scanf("%d%d",&u,&v); 90 addQuqry(u,v,i); 91 } 92 Tarjan(); 93 for(int i=1;i <= q;++i) 94 printf("%d\n",res[i]); 95 }
二分+LCA:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 #define pb(x) push_back(x) 7 const int maxn=5e4+50; 8 9 int n,q; 10 int fa[20][maxn]; 11 int dist[maxn]; 12 int depth[maxn]; 13 struct Node 14 { 15 int to; 16 int w; 17 Node(int to,int w):to(to),w(w){} 18 }; 19 vector<Node >edge[maxn]; 20 void addEdge(int u,int v,int w) 21 { 22 edge[u].pb(Node(v,w)); 23 edge[v].pb(Node(u,w)); 24 } 25 //==============LCA============ 26 void Dfs(int v,int f,int d,int l) 27 { 28 depth[v]=d; 29 dist[v]=l; 30 fa[0][v]=f; 31 for(int i=0;i < edge[v].size();i++) 32 { 33 int to=edge[v][i].to; 34 int w=edge[v][i].w; 35 if(to != f) 36 Dfs(to,v,d+1,l+w); 37 } 38 } 39 int LCA(int u,int v)//it faster than the method in book 40 { 41 if(depth[u] > depth[v]) 42 swap(u,v);//guarantee depth[v] > depth[u] 43 int i; 44 for(i=0;(1<<i) <= depth[v];i++);//find the max k that v can << 45 i--; 46 for(int k=i;k >= 0;--k) 47 if((depth[v]-(1<<k)) >= depth[u]) 48 v=fa[k][v]; 49 if(v == u) 50 return v; 51 for(int k=i;k >= 0;--k) 52 if(fa[k][v] != -1 && fa[k][v] != fa[k][u]) 53 { 54 u=fa[k][u]; 55 v=fa[k][v]; 56 } 57 return fa[0][v]; 58 } 59 void Pretreat() 60 { 61 for(int i=1;i <= n;++i) 62 if(!depth[i]) 63 Dfs(i,-1,0,0); 64 for(int k=0;k+1 < 20;k++) 65 for(int v=1;v <= n;++v) 66 if(fa[k][v] == -1) 67 fa[k+1][v]=-1; 68 else 69 fa[k+1][v]=fa[k][fa[k][v]]; 70 } 71 //============================= 72 void Init() 73 { 74 memset(depth,0,sizeof(depth)); 75 } 76 int main() 77 { 78 Init(); 79 scanf("%d",&n); 80 for(int i=1;i < n;i++) 81 { 82 int u,v,w; 83 scanf("%d%d%d",&u,&v,&w); 84 addEdge(u,v,w); 85 } 86 Pretreat(); 87 scanf("%d",&q); 88 for(int i=1;i <= q;++i) 89 { 90 int u,v; 91 scanf("%d%d",&u,&v); 92 int lca=LCA(u,v); 93 printf("%d\n",dist[u]+dist[v]-2*dist[lca]); 94 } 95 }