• How far away ? HDU


    LCA应用求最短路

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int N=40005;
    int T,n,m,ans,tot;
    struct node{
    	int to,next,w;
    }edge[N<<1];
    int head[N],dep[N];
    int f[N][30],dis[N][30];
    void init(){
    	tot=0;
    	memset(edge,0,sizeof(edge));
    	memset(head,-1,sizeof(head));
    	memset(dep,0,sizeof(dep));
    	memset(dis,0,sizeof(dis));
    }
    void add(int u,int v,int w){
    	edge[tot].to=v;
    	edge[tot].next=head[u];
    	edge[tot].w=w;
    	head[u]=tot++;
    }
    void dfs(int u,int fa){
    	f[u][0]=fa; dep[u]=dep[fa]+1;
    	for(int j=1;(1<<j)<=dep[u];j++){
    		f[u][j]=f[f[u][j-1]][j-1];
    		dis[u][j]=dis[u][j-1]+dis[f[u][j-1]][j-1];
    	}
    	for(int i=head[u];i!=-1;i=edge[i].next){
    		int v=edge[i].to;
    		if(v!=fa){
    			dis[v][0]=edge[i].w;
    			dfs(v,u);
    		}
    	} 
    }
    int lca(int u,int v){
    	if(dep[u]<dep[v]) swap(u,v);
    	if(dep[u]!=dep[v]){
    		for(int j=20;j>=0;j--){
    			if(dep[f[u][j]]>=dep[v]){
    				ans+=dis[u][j];
    				u=f[u][j];
    			}
    		}
    	}
    	if(u==v) return ans;
    	for(int j=20;j>=0;j--){
    		if(f[u][j]!=f[v][j]){
    			ans+=dis[u][j];
    			ans+=dis[v][j];
    			u=f[u][j];
    			v=f[v][j];
    		}
    	}
    	return ans+dis[u][0]+dis[v][0];
    }
    int main(){
    	scanf("%d",&T);
    	while(T--){
    		init();
    		int n,m;
    		scanf("%d%d",&n,&m);
    		for(int i=1;i<n;i++){
    			int x,y,z;
    			scanf("%d%d%d",&x,&y,&z);
    			add(x,y,z); add(y,x,z);
    		}
    		dfs(1,0);
    		for(int i=1;i<=m;i++){
    			ans=0;
    			int x,y;
    			scanf("%d%d",&x,&y);
    			printf("%d
    ",lca(x,y));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    函数--第一类对象、闭包、
    递归
    局部变量 和 全局变量
    默认参数,不固定参数 *args,**kwargs
    函数基本语法及特性
    文件修改
    文件操作,重点,日常使用!!!
    集合
    重新写了一边三级菜单,加了一些自己的理解
    三级菜单
  • 原文地址:https://www.cnblogs.com/New-ljx/p/14828531.html
Copyright © 2020-2023  润新知