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 }