[练习] LCA练习1(最基础)

来源:互联网 发布:世界历史数据库 编辑:程序博客网 时间:2024/06/11 04:35

hdu 2586 How Far Away?

lca求最短距离(模板题)

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<cmath>#define N 40005using namespace std;int n,m;int num=0;int b[2*N],w[2*N],nt[2*N],p[2*N];int fa[N][20],d[N],val[N];void  insert(){num=0;scanf("%d%d",&n,&m);for(int i=1;i<=n-1;i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);num++;b[num]=y;w[num]=z;nt[num]=p[x];p[x]=num;num++;b[num]=x;w[num]=z;nt[num]=p[y];p[y]=num;}}void dfs(int x,int h){d[x]=h;for(int i=1;i<=20;i++){        if(d[x]<(1<<i))break;fa[x][i]=fa[fa[x][i-1]][i-1];}for(int i=p[x];i;i=nt[i]){int v=b[i];if(v==fa[x][0]) continue;fa[v][0]=x;val[v]=val[x]+w[i];dfs(v,h+1);}}int lca(int x,int y){if(d[x]<d[y]) swap(x,y);int t=d[x]-d[y];for(int i=0;i<=20;i++){if(t&(1<<i))x=fa[x][i];}if(x==y) return x;for(int i=20;i>=0;i--){if(fa[x][i]!=fa[y][i]){x=fa[x][i];y=fa[y][i];}}return fa[x][0];}void solve(){memset(fa,0,sizeof(fa));memset(p,0,sizeof(p));memset(val,0,sizeof(val));insert();dfs(1,0);while(m--){int x,y;scanf("%d%d",&x,&y);int t=lca(x,y);printf("%d\n",val[x]+val[y]-2*val[t]);}}int main(){int T;scanf("%d",&T);while(T--){solve();}return 0;}

P3379 【模板】最近公共祖先(LCA)

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<cmath>#define M 500001#define N 500001using namespace std;int n,m,s;int num=0;int b[2*M],w[2*M],nt[2*M],p[N];int fa[M][20],d[M];void insert(){scanf("%d%d%d",&n,&m,&s);for(int i=1;i<=n-1;i++){int x,y;scanf("%d%d",&x,&y);num++;b[num]=y;nt[num]=p[x];p[x]=num;num++;b[num]=x;nt[num]=p[y];p[y]=num;}}void dfs(int x){for(int i=1;i<=20;i++){if(d[x]<(1<<i)) break;fa[x][i]=fa[fa[x][i-1]][i-1];} for(int i=p[x];i>0;i=nt[i]){int v=b[i];if(v==fa[x][0]) continue;fa[v][0]=x;d[v]=d[x]+1;        dfs(v);}}int lca(int x,int y){int h;if(d[x]<d[y]) swap(x,y);for(h=0;(1<<h)<=d[x];h++);h--;for(int i=h;i>=0;i--){if(d[x]-(1<<i)>=d[y])x=fa[x][i];}/*或者可以写成int t=d[x]-d[y];for(int i=0;i<=20;i++){if(t&(1<<i))x=fa[x][i];}利用位运算 20的解释同上 */if(x==y) return x;for(int i=h;i>=0;i--){ if(fa[x][i]!=fa[y][i]){x=fa[x][i];y=fa[y][i];}}return fa[x][0]; } int main(){insert();dfs(s);int x,y;for(int i=1;i<=m;i++){scanf("%d%d",&x,&y);printf("%d\n",lca(x,y));}return 0;}

 P2912 [USACO08OCT]牧场散步Pasture Walking

#include<iostream>#include<cstdio>#include<cstring>using namespace std;int n,q,cnt;int deep[1001],head[1001],dis[1001],fa[1001][11];bool vis[1001];struct data{int to,next,v;}e[2001];void ins(int u,int v,int w){e[++cnt].to=v;e[cnt].next=head[u];e[cnt].v=w;head[u]=cnt;}void insert(int u,int v,int w){ins(u,v,w);ins(v,u,w);}void dfs(int x){    vis[x]=1;    for(int i=1;i<=9;i++)    {        if(deep[x]<(1<<i))break;        fa[x][i]=fa[fa[x][i-1]][i-1];    }    for(int i=head[x];i;i=e[i].next)    {        if(vis[e[i].to])continue;        deep[e[i].to]=deep[x]+1;        dis[e[i].to]=dis[x]+e[i].v;        fa[e[i].to][0]=x;        dfs(e[i].to);    }}int lca(int x,int y){    if(deep[x]<deep[y])swap(x,y);    int d=deep[x]-deep[y];    for(int i=0;i<=9;i++)       if((1<<i)&d)x=fa[x][i];    for(int i=9;i>=0;i--)       if(fa[x][i]!=fa[y][i])           {x=fa[x][i];y=fa[y][i];}    if(x==y)return x;    else return fa[x][0];}int main(){    scanf("%d%d",&n,&q);    for(int i=1;i<n;i++)    {        int u,v,w;        scanf("%d%d%d",&u,&v,&w);        insert(u,v,w);    }    dfs(1);    for(int i=1;i<=q;i++)    {        int x,y;        scanf("%d%d",&x,&y);        printf("%d\n",dis[x]+dis[y]-2*dis[lca(x,y)]);    }    return 0;}


原创粉丝点击