【HDU 2586】LCA模版题

来源:互联网 发布:淘宝同款图片 编辑:程序博客网 时间:2024/06/08 11:01

练习LCA->RMQ的求法。qwq

#include<bits/stdc++.h>using namespace std;#define g() getchar()#define d(x) isdigit(x)#define rep(i,s,t) for(int i=(s);i<=(t);i++)#define N 40010char ch;template<class T>inline void F(T& x){    for(ch=g();!d(ch);ch=g());    for(x=0;d(ch);x=x*10+ch-'0',ch=g());}struct Edge{int to,w,next;}e[N<<1];int T,head[N],n,m,eid=1,tot,dis[N],hs[N<<1],vis[N];inline void adde(int u,int v,int w){e[eid].to=v;e[eid].w=w;e[eid].next=head[u];head[u]=eid++;}int deep[N<<1],first[N];void dfs(int u,int dep){    hs[++tot]=u;vis[u]=T;deep[tot]=dep;first[u]=tot;    for(int i=head[u];~i;i=e[i].next)if(vis[e[i].to]!=T){        dis[e[i].to] = dis[u]+e[i].w;        dfs(e[i].to,dep+1);        hs[++tot]=u;deep[tot]=dep;          }}int st[N<<1][25];void getST(int len){    int a,b;    for(int i=1;i<=len;i++)st[i][0]=i;    for(int j=1;(1<<j)<=n;j++){        for(int i=0;i+(1<<j)-1<=len;i++){            a = st[i][j-1],b=st[i+(1<<(j-1))][j-1];            if(deep[a]<deep[b])st[i][j]=a;            else st[i][j] = b;        }    }}int RMQ(int x,int y){    int block = log(y-x+1.0)/log(2.0);    int a = st[x][block],b = st[y-(1<<block)+1][block];    if(deep[a]<deep[b])return a;    else return b;}int LCA(int u,int v){    int x = first[u],y=first[v];    if(x>y)swap(x,y);    return hs[RMQ(x,y)];        }int main(){    F(T);int a,b,c;memset(vis,0x3f,sizeof(vis));    while(T--){        memset(head,-1,sizeof(head));eid=1;        F(n),F(m);        rep(i,1,n-1){F(a),F(b),F(c);adde(a,b,c),adde(b,a,c);}        tot = 0;dis[1]=0;dfs(1,1);        getST(2*n-1);        while(m--){            F(a),F(b);            printf("%d\n",dis[a]+dis[b]-2*dis[LCA(a,b)]);        }    }    return 0;}
1 0