在线lca算法模板

来源:互联网 发布:清华经管北大光华知乎 编辑:程序博客网 时间:2024/05/21 09:21

题目:http://acm.hdu.edu.cn/showproblem.php?pid=2586

题意:求树上两点间距离

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;const int N = 100100;struct edge{    int to, cost, next;}g[N*2];int dp[20][N*2];//dp[i][j]记录的是以j为起点、2的i次方长度内的深度最小点的编号,因为访问2n-1次,数组长度要乘2int n, m;int cnt, tot, head[N];bool vis[N];int dep[N*2], ver[N*2], fir[N], dis[N]; //ver为访问的节点依次编号,dep记录编号对应的节点的深度,因为访问2n-1次,所有这两个数组长度乘2void add_edge(int v, int u, int cost){    g[cnt].to = u, g[cnt].cost = cost, g[cnt].next = head[v], head[v] = cnt++;}void dfs(int v, int cur){    vis[v] = true, ver[++tot] = v, dep[tot] = cur, fir[v] = tot;    for(int i = head[v]; i != -1; i = g[i].next)    {        int u = g[i].to;        if(! vis[u])        {            dis[u] = dis[v] + g[i].cost;            dfs(u, cur + 1);            ver[++tot] = v, dep[tot] = cur;        }    }}void ST(int n){    for(int i = 1; i <= n; i++)        dp[0][i] = i;    for(int i = 1; (1<<i) <= n; i++)        for(int j = 1; j <= n - (1<<i) + 1; j++)            dp[i][j] = dep[dp[i-1][j]] < dep[dp[i-1][j+(1<<(i-1))]] ? dp[i-1][j] : dp[i-1][j+(1<<(i-1))];}int rmq(int v, int u){    int k = (int)log2(u - v + 1);    return dep[dp[k][v]] < dep[dp[k][u-(1<<k)+1]] ? dp[k][v] : dp[k][u-(1<<k)+1];}int lca(int v, int u){    v = fir[v], u = fir[u];    if(v > u) swap(v, u);    int res = rmq(v, u);    return ver[res];}int main(){    int t, a, b, c;    scanf("%d", &t);    while(t--)    {        scanf("%d%d", &n, &m);        cnt = 0;        memset(head, -1, sizeof head);        for(int i = 0; i < n - 1; i++)        {            scanf("%d%d%d", &a, &b, &c);            add_edge(a, b, c);            add_edge(b, a, c);        }        memset(vis, 0, sizeof vis);        dis[1] = 0;        tot = 0;        dfs(1, 1);        ST(2 * n - 1);        for(int i = 0; i < m; i++)        {            scanf("%d%d", &a, &b);            int res = lca(a, b);            printf("%d\n", dis[a] + dis[b] - 2 * dis[res]);        }    }    return 0;}


0 0
原创粉丝点击