zoukankan      html  css  js  c++  java
  • [练习] LCA练习1(最基础) 2017-06-02 11:54 39人阅读 评论(0) 收藏

    hdu 2586 How Far Away?

    lca求最短距离(模板题)

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define N 40005
    using 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
    ",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 500001
    using 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
    ",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
    ",dis[x]+dis[y]-2*dis[lca(x,y)]);
        }
        return 0;
    }


  • 相关阅读:
    poj 3243 Clever Y(BabyStep GiantStep)
    poj 2417 Discrete Logging
    poj 3481 Double Queue
    hdu 4046 Panda
    hdu 2896 病毒侵袭
    poj 1442 Black Box
    hdu 2815 Mod Tree
    hdu 3065 病毒侵袭持续中
    hdu 1576 A/B
    所有控件
  • 原文地址:https://www.cnblogs.com/xljxlj/p/7183631.html
Copyright © 2011-2022 走看看