zoj 3195 Design the city

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("******\n")
 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("\n");
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\n", (dis[x] + dis[y] + dis[z]) -  (dis[lcaxy] + dis[lcayz] + dis[lcazx]));
124         }
125     }
126     return  0;
127 }

猜你喜欢

转载自www.cnblogs.com/qldabiaoge/p/9447475.html
ZOJ
今日推荐