首页 > 代码库 > POJ 1986 Distance Queries

POJ 1986 Distance Queries

http://poj.org/problem?id=1986

题意:一棵树里找到两个点的距离。(不用考虑不联通的情况)

题解:LCA模板题。

  1 #include <iostream>  2 #include <algorithm>  3 #include <cstring>  4 #include <string>  5 #include <cstdio>  6 #include <cmath>  7 #include <queue>  8 #include <map>  9 #include <set> 10  11 #define eps 1e-5 12 #define MAXN 55555 13 #define MAXM 111111 14 #define INF 1000000000 15 using namespace std; 16 int n, m, q; 17 struct edge 18 { 19     int v, next, w; 20 }es[MAXM]; 21 int head[MAXN], e; 22 int ide,tmpdfn; 23 int f[2 * MAXN], id[MAXN], used[MAXN], pos[MAXN], dis[MAXN]; 24 int mi[2 * MAXN][18]; 25  26 void init() 27 { 28     memset(head, -1, sizeof(head)); 29     e = 0; 30     ide = tmpdfn = 0; 31     memset(used, 0, sizeof(used)); 32     dis[1] = 0; 33 } 34  35 void add(int u, int v, int w) 36 { 37     es[e].v = v; 38     es[e].w = w; 39     es[e].next = head[u]; 40     head[u] = e++; 41 } 42 void dfs(int u) 43 { 44     used[u] = 1; 45     int tmp = ++tmpdfn; 46     f[++ide] = tmp; 47     id[tmp] = u; 48     pos[u] = ide; 49     for(int i = head[u]; i != -1; i = es[i].next) 50     { 51         int v = es[i].v; 52         if(!used[v]) 53         { 54             dis[v] = dis[u] + es[i].w; 55             dfs(v); 56             f[++ide] = tmp; 57         } 58     } 59      60 } 61 void rmqinit(int n, int *w) 62 { 63     for(int i = 1; i <= n; i++) mi[i][0] = w[i]; 64     int m = (int)(log(n * 1.0) / log(2.0)); 65     for(int i = 1; i <= m; i++) 66         for(int j = 1; j <= n; j++) 67         { 68             mi[j][i] = mi[j][i - 1]; 69             if(j + (1 << (i - 1)) <= n) mi[j][i] = min(mi[j][i], mi[j + (1 << (i - 1))][i - 1]); 70         } 71 } 72  73 int rmqmin(int l,int r) 74 { 75     int m = (int)(log((r - l + 1) * 1.0) / log(2.0)); 76     return min(mi[l][m] , mi[r - (1 << m) + 1][m]); 77 } 78  79 int LCA(int l, int r) 80 { 81     if(pos[l] > pos[r]) swap(l, r); 82     int ans = rmqmin(pos[l], pos[r]); 83     return id[ans]; 84 } 85 int main() 86 { 87    // freopen("/Users/apple/Desktop/题/POJ 1986_1/POJ 1986_1/in","r",stdin); 88     scanf("%d%d", &n, &m); 89     int u, v, w, l, r; 90     init(); 91     while(m--) 92     { 93         scanf("%d%d%d%*s", &u, &v, &w); 94         add(u, v, w); 95         add(v, u, w); 96     } 97     dfs(1); 98     rmqinit(ide, f); 99     scanf("%d", &q);100     while(q--)101     {102         scanf("%d%d", &l, &r);103         printf("%d\n", dis[l] + dis[r] - 2 * dis[LCA(l, r)]);104     }105     return 0;106 }

 

POJ 1986 Distance Queries