LCA
题意:给一个无根树,有q个询问,每个询问3个点,问将这3个点连起来,距离最短是多少,
LCA的模板题,分别求LCA(X,Y),LCA(X,Z),LCA(Y,Z),
和对应的距离,然后3个距离相加再除以2就是这个询问的结果
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <cmath> 5 #include <algorithm> 6 #include <set> 7 #include <iostream> 8 #include <map> 9 #include <stack> 10 #include <string> 11 #include <vector> 12 #define pi acos(-1.0) 13 #define eps 1e-6 14 #define fi first 15 #define se second 16 #define lson l,m,rt<<1 17 #define rson m+1,r,rt<<1|1 18 #define bug printf("****** ") 19 #define mem(a,b) memset(a,b,sizeof(a)) 20 #define fuck(x) cout<<"["<<x<<"]"<<endl 21 #define f(a) a*a 22 #define sf(n) scanf("%d", &n) 23 #define sff(a,b) scanf("%d %d", &a, &b) 24 #define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c) 25 #define sffff(a,b,c,d) scanf("%d %d %d %d", &a, &b, &c, &d) 26 #define pf printf 27 #define FRE(i,a,b) for(i = a; i <= b; i++) 28 #define FREE(i,a,b) for(i = a; i >= b; i--) 29 #define FRL(i,a,b) for(i = a; i < b; i++) 30 #define FRLL(i,a,b) for(i = a; i > b; i--) 31 #define FIN freopen("DATA.txt","r",stdin) 32 #define gcd(a,b) __gcd(a,b) 33 #define lowbit(x) x&-x 34 #pragma comment (linker,"/STACK:102400000,102400000") 35 using namespace std; 36 typedef long long LL; 37 typedef unsigned long long ULL; 38 const int maxn = 1e5 + 10; 39 int _pow[maxn], dep[maxn], dis[maxn], vis[maxn], ver[maxn]; 40 int tot, head[maxn], dp[maxn * 2][25], k, first[maxn], fa[maxn]; 41 struct node { 42 int u, v, w, nxt; 43 } edge[maxn << 2]; 44 void init() { 45 tot = 0; 46 mem(head, -1); 47 for (int i = 0 ; i < maxn ; i++) fa[i] = i; 48 } 49 int Find(int x) { 50 return x == fa[x] ? fa[x] : fa[x] = Find(fa[x]); 51 } 52 void combine(int x, int y) { 53 int nx = Find(x), ny = Find(y); 54 if(nx != ny) fa[nx] = ny; 55 return ; 56 } 57 void add(int u, int v, int w) { 58 edge[tot].v = v, edge[tot].u = u; 59 edge[tot].w = w, edge[tot].nxt = head[u]; 60 head[u] = tot++; 61 } 62 void dfs(int u, int DEP) { 63 vis[u] = 1; 64 ver[++k] = u; 65 first[u] = k; 66 dep[k] = DEP; 67 for (int i = head[u]; ~i; i = edge[i].nxt) { 68 if (vis[edge[i].v]) continue; 69 int v = edge[i].v, w = edge[i].w; 70 dis[v] = dis[u] + w; 71 dfs(v, DEP + 1); 72 ver[++k] = u; 73 dep[k] = DEP; 74 } 75 } 76 void ST(int len) { 77 int K = (int)(log((double)len) / log(2.0)); 78 for (int i = 1 ; i <= len ; i++) dp[i][0] = i; 79 for (int j = 1 ; j <= K ; j++) { 80 for (int i = 1 ; i + _pow[j] - 1 <= len ; i++) { 81 int a = dp[i][j - 1], b = dp[i + _pow[j - 1]][j - 1]; 82 if (dep[a] < dep[b]) dp[i][j] = a; 83 else dp[i][j] = b; 84 } 85 } 86 } 87 int RMQ(int x, int y) { 88 int K = (int)(log((double)(y - x + 1)) / log(2.0)); 89 int a = dp[x][K], b = dp[y - _pow[K] + 1][K]; 90 if (dep[a] < dep[b]) return a; 91 else return b; 92 } 93 int LCA(int u, int v) { 94 int x = first[u], y = first[v]; 95 if (x > y) swap(x, y); 96 int ret = RMQ(x, y); 97 return ver[ret]; 98 } 99 int main() { 100 for (int i = 0 ; i < 40 ; i++) _pow[i] = (1 << i); 101 int n, q; 102 int cas = 0; 103 while(~sf(n)) { 104 init(); 105 mem(vis, 0); 106 if (cas++) printf(" "); 107 for (int i = 0 ; i < n - 1 ; i++) { 108 int u, v, w; 109 sfff(u, v, w); 110 add(u, v, w); 111 add(v, u, w); 112 } 113 k = 0, dis[0] = 0; 114 dfs(0, 1); 115 ST(2 * n - 1); 116 sf(q); 117 while(q--) { 118 int x, y, z; 119 sfff(x, y, z); 120 int lcaxy = LCA(x, y); 121 int lcayz = LCA(y, z); 122 int lcazx = LCA(z, x); 123 printf("%d ", (dis[x] + dis[y] + dis[z]) - (dis[lcaxy] + dis[lcayz] + dis[lcazx])); 124 } 125 } 126 return 0; 127 }