lca模板 hdu 2586

来源:互联网 发布:淘宝上买到假药怎么办 编辑:程序博客网 时间:2024/05/18 13:25

在线 RMQ

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include<iostream>#include<algorithm>#include<stack>#include<queue>#include<vector>#include<set>#include<map>#include<string>using namespace std;typedef long long ll;const int INF=0x3f3f3f3f;int n;int vis[40010],id[40010],depth[40010*2],vs[40010*2],ans[40010];int dp[40010*2][30];struct node1{    int b,c;};vector<node1> vec[40010],node[40010];void rmq_init(int len){    for(int i=0;i<=len;i++)        dp[i][0]=i;    for(int j=1;(1<<j)<=len;j++)        for(int i=1;i+(1<<j)-1<=len;i++)        {            int a=dp[i][j-1],b=dp[i+(1<<(j-1))][j-1];            dp[i][j]=depth[a]<depth[b]?a:b;        }}int rmq(int l,int r){    int k=0;    while((1<<(k+1))<=r-l+1)        k++;    int a=dp[l][k],b=dp[r-(1<<k)+1][k];    return depth[a]<depth[b]?a:b;}int lca(int u,int v){    int x=id[u];    int y=id[v];    if(x>y)        swap(x,y);    return vs[rmq(x,y)];}void dfs(int v,int p,int d,int &k){    id[v]=k;    vs[k]=v;    depth[k++]=d;    for(int i=0;i<vec[v].size();i++)    {        node1 pp=vec[v][i];        if(pp.b!=p)        {            ans[pp.b]=ans[v]+pp.c;            dfs(pp.b,v,d+1,k);            vs[k]=v;            depth[k++]=d;        }    }}void init(int x){    int k=0;    dfs(x,-1,0,k);    rmq_init(n*2-1);}int main(){    int t;    scanf("%d",&t);    while(t--)    {        memset(vis,0,sizeof(vis));        memset(ans,0,sizeof(ans));        int q,nn;        scanf("%d%d",&n,&q);        nn=n-1;        int a,b,c;        while(nn--)        {            scanf("%d%d%d",&a,&b,&c);            node1 p1,p2;            p1.b=b,p1.c=c;            p2.b=a,p2.c=c;            vec[a].push_back(p1);            vec[b].push_back(p2);            vis[b]=1;        }        int keep;        for(int i=1;i<=n;i++)        {            if(!vis[i])            {                keep=i;                break;            }        }        ans[keep]=0;        init(keep);        for(int i=0;i<q;i++)        {            scanf("%d%d",&a,&b);            int v=lca(a,b);            printf("%d\n",ans[a]+ans[b]-2*ans[v]);        }    }    return 0;}

离线 targin

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include<iostream>#include<algorithm>#include<stack>#include<queue>#include<vector>#include<set>#include<map>#include<string>using namespace std;typedef long long ll;const int INF=0x3f3f3f3f;int n;int pre[40010],rankk[40010],vis[40010],ans[40010],dis[40010];vector<int>num[40010],w[40010],vec[40010],node[40010];void init(){    for(int i=0;i<=n;i++)    {        vec[i].clear();        node[i].clear();        num[i].clear();        w[i].clear();        vis[i]=0;        pre[i]=i;        rankk[i]=1;        ans[i]=0;        dis[i]=0;    }}int findd(int x){   if(x==pre[x])        return x;    return findd(pre[x]);}void unite(int a,int b){    a=findd(a);    b=findd(b);    if(a==b)        return;    pre[b]=a;}void dfs(int x,int val){    vis[x]=1;    dis[x]=val;    for(int i=0;i<vec[x].size();i++)    {        int v=vec[x][i];        if(vis[v])            continue;        dfs(v,val+w[x][i]);        unite(x,v);    }    for(int i=0;i<node[x].size();i++)    {        int v=node[x][i];        if(vis[v])        {            ans[num[x][i]]=dis[x]+dis[v]-2*dis[findd(v)];        }    }}int main(){    int t;    scanf("%d",&t);    while(t--)    {        int q,nn;        scanf("%d%d",&n,&q);        init();        nn=n-1;        int a,b,c;        while(nn--)        {            scanf("%d%d%d",&a,&b,&c);            vec[a].push_back(b);            vec[b].push_back(a);            w[a].push_back(c);            w[b].push_back(c);        }        for(int i=0;i<q;i++)        {            scanf("%d%d",&a,&b);            node[a].push_back(b);            node[b].push_back(a);            num[a].push_back(i);            num[b].push_back(i);        }        dfs(1,0);        for(int i=0;i<q;i++)            printf("%d\n",ans[i]);    }    return 0;}


在线 倍增

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include<iostream>#include<algorithm>#include<stack>#include<queue>#include<vector>#include<set>#include<map>#include<string>using namespace std;typedef long long ll;const int INF=0x3f3f3f3f;int n;int vis[40010],depth[40010],pre[30][40010],ans[40010];struct node1{    int b,c;};vector<node1> vec[40010];void dfs(int u,int fa,int d){    pre[0][u]=fa;    depth[u]=d;    for(int i=0;i<vec[u].size();i++)    {        node1 v=vec[u][i];        if(v.b!=fa)        {            ans[v.b]=ans[u]+v.c;            dfs(v.b,u,d+1);        }    }}void init(int x){    dfs(x,-1,0);    for(int k=0;(1<<(k+1))<n;k++)    {        for(int v=0;v<n;v++)        {            if(pre[k][v]<0)                pre[k+1][v]=-1;            else                pre[k+1][v]=pre[k][pre[k][v]];        }    }}int lca(int u,int v){    int t=0;    while((1<<t)<=n)        t++;    if(depth[u]>depth[v])        swap(u,v);    for(int k=0;k<t;k++)    {        if((depth[v]-depth[u])>>k&1)            v=pre[k][v];    }    if(u==v)        return u;    for(int k=t-1;k>=0;k--)    {        if(pre[k][u]!=pre[k][v])        {            u=pre[k][u];            v=pre[k][v];        }    }    return pre[0][u];}int main(){    int t;    scanf("%d",&t);    while(t--)    {        memset(vis,0,sizeof(vis));        memset(ans,0,sizeof(ans));        int q,nn;        scanf("%d%d",&n,&q);        nn=n-1;        int a,b,c;        while(nn--)        {            scanf("%d%d%d",&a,&b,&c);            node1 p1,p2;            p1.b=b,p1.c=c;            p2.b=a,p2.c=c;            vec[a].push_back(p1);            vec[b].push_back(p2);            vis[b]=1;        }        int keep;        for(int i=1;i<=n;i++)        {            if(!vis[i])            {                keep=i;                break;            }        }        ans[keep]=0;        init(keep);        for(int i=0;i<q;i++)        {            scanf("%d%d",&a,&b);            int v=lca(a,b);            printf("%d\n",ans[a]+ans[b]-2*ans[v]);        }    }    return 0;}



1 0