• 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("******
    ")
     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 }
  • 相关阅读:
    URAL 1993 This cheeseburger you don't need
    python获取教务管理系统的MM照片
    ZOJ 3175 Number of Containers 分块
    ZOJ 3435 Ideal Puzzle Bobble 莫比乌斯反演
    整理各种线性筛法
    SPOJ 7001 Visible Lattice Points 莫比乌斯反演
    UVA 11997 K Smallest Sums
    HDU 4768 Flyer 二分
    HDU 4135 Co-prime 容斥
    POJ 3468 A Simple Problem with Integers 线段树
  • 原文地址:https://www.cnblogs.com/qldabiaoge/p/9447475.html
Copyright © 2020-2023  润新知