Click to open link
Test instructions: Enter N, next n-1 line, each line a,b,c represents a and B has a weight of C, two-way edge, M inquiry, ask the shortest distance so that a,b,c can connect
Idea: LCA template problem, nothing to say, see the theory of the words on the internet a lot of weak said, the code has comments, to help understand
#include <vector> #include <stdio.h> #include <string.h> #include <stdlib.h> #include < Iostream> #include <algorithm>using namespace std;typedef long long ll;const int Inf=0x3f3f3f3f;const int maxn= 50010;struct edge{int to,cost; Edge (int a,int b) {to=a;cost=b;}}; Vector<edge>g[maxn];bool Vis[maxn];int l[maxn*2],e[maxn*2],h[maxn],dis[maxn],dp[2*maxn][20];// h for the first occurrence of each element, E for the sequence number of DFS traversal, l for depth, dis for each point to the root of the distance//dp[i][j] represents the I to j depth of the smallest position int k,n;void dfs (int t,int deep) {k++; e[k]=t; L[k]=deep; h[t]=k;//the leaves will appear only once in e, and not the leaf nodes will appear multiple times for (unsigned int i=0;i<g[t].size () i++) {edge tt=g[t][i]; if (!vis[tt.to]) {//appears no further, ensure the size of dis and the position of H first occurrence vis[tt.to]=1; Dis[tt.to]=dis[t]+tt.cost; DFS (TT.TO,DEEP+1); k++; e[k]=t; L[k]=deep; }}}void Rmq_init () {//RMQ St Algorithm for (int i=1;i<=2*n-1;i++) dp[i][0]=i; for (int i=1, (1<<i) <=2*n-1;i++) {for (int j=1;j+ (1<<i) -1<=2*n-1;j++) { if (l[dp[j][i-1]]<l[dp[j+ (1<< (i-1))][i-1]]) dp[j][i]=dp[j][i-1]; Else dp[j][i]=dp[j+ (1<< (i-1))][i-1]; }}}int RMQ (int le,int ri) {le=h[le];ri=h[ri];//Find the first occurrence position if (Le>ri) swap (Le,ri),//le greater than Ri description ri appears before LE, swaps int kk=0; while ((1<< (kk+1)) <=ri-le+1) kk++; if (l[dp[le][kk]]<l[dp[ri-(1<<KK) +1][KK]]) return E[DP[LE][KK]]; else return e[dp[ri-(1<<KK) +1][kk]];//returns the value of the DP position}int main () {int q,a,b,c; int flag=0; while (scanf ("%d", &n)!=-1) {for (int i=0;i<maxn;i++) g[i].clear (); if (flag==0) flag=1; else printf ("\ n"); memset (dis,0,sizeof (dis)); memset (vis,0,sizeof (VIS)); for (int i=0;i<n-1;i++) {scanf ("%d%d%d", &a,&b,&c); G[a].push_back (Edge (b,c)); G[b].push_back (Edge (a,c)); } k=0;vis[0]=1; DFS (0,1); Rmq_init (); scanf ("%d", &q); while (q--) {scanf ("%d%d%d",&a,&b,&c); int ans=dis[a]+dis[b]+dis[c]-(DIS[RMQ (A, B)]+dis[rmq (a,c)]+DIS[RMQ (b,c)]); This drawing can be seen by the printf ("%d\n", ans); }} return 0;}
ZOJ 3195 LCA Transfer RMQ