zoukankan      html  css  js  c++  java
  • LCA【bzoj3364】: [Usaco2004 Feb]Distance Queries 距离咨询

    【bzoj3364】: [Usaco2004 Feb]Distance Queries 距离咨询

    Description

    ​ 奶牛们拒绝跑马拉松,因为她们悠闲的生活无法承受约翰选择的如此长的赛道.因此约翰决心找一条更合理的赛道,他打算咨询你.此题的地图形式与前两题相同.但读入地图之后,会有K个问题.每个问题包括2个整数,就是约翰感兴趣的2个农场的编号,请尽快算出这2个农场间的距离.

    Input

    ​ 第1到I+M行:与前两题相同;

    ​ 第2+M行:一个整数K(1≤K≤10000).

    ​ 第3+M到2+M+K行:每行输入2个整数,代表两个农场.

    Output

    ​ 对每个问题,输出单独的一个整数,给出正确的距离.

    倍增模板题。

    注意long long RE了好几次。

    code:

    #include<iostream>
    #include<cstdio>
    #define int long long
    using namespace std;
    const int wx=40017;
    inline int read(){
    	int sum=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0';ch=getchar();}
    	return sum*f;
    }
    int n,m,num;
    int head[wx],dep[wx],f[wx][18],dis[wx][18];
    struct e{
    	int nxt,to,dis;
    }edge[wx*2];
    void add(int from,int to,int dis){
    	edge[++num].nxt=head[from];
    	edge[num].to=to;
    	edge[num].dis=dis;
    	head[from]=num;
    }
    void dfs(int u,int fa){
    	dep[u]=dep[fa]+1;
    	for(int i=head[u];i;i=edge[i].nxt){
    		int v=edge[i].to;
    		if(v==fa)continue;
    		f[v][0]=u;dis[v][0]=edge[i].dis;
    		dfs(v,u);
    	}
    }
    void pre(){
    	for(int j=1;j<=17;j++){
    		for(int i=1;i<=n;i++){
    			f[i][j]=f[f[i][j-1]][j-1];
    			dis[i][j]=dis[i][j-1]+dis[f[i][j-1]][j-1];
    		}
    	}
    }
    int LCA(int x,int y){
    	int re=0;
    	if(dep[x]<dep[y])swap(x,y);
    	for(int i=17;i>=0;i--){
    		if(dep[f[x][i]]>=dep[y]){
    			re+=dis[x][i];x=f[x][i];
    		}
    	}
    	if(x==y)return re;
    	for(int i=17;i>=0;i--){
    		if(f[x][i]!=f[y][i]){
    			re+=dis[x][i];re+=dis[y][i];
    			x=f[x][i],y=f[y][i];
    		}
    	}
    	return re+dis[x][0]+dis[y][0];
    }
    signed main(){
    	n=read();read();
    	for(int i=1;i<n;i++){
    		int x,y,z;
    		x=read();y=read();z=read();scanf("%s");
    		add(x,y,z);add(y,x,z);
    	}
    	dfs(1,0);pre();
    	m=read();
    	for(int i=1;i<=m;i++){
    		int x,y;
    		x=read();y=read();
    		printf("%d
    ",LCA(x,y));
    	}
    	return 0;
    }
    
  • 相关阅读:
    poj 2488 DFS
    畅通工程 并查集模版
    KMP 模板
    poj 1426 DFS
    poj 2528 线段数
    poj 3468 线段数 修改区间(点)
    CVPR2012文章阅读(2)A Unified Approach to Salient Object Detection via Low Rank Matrix Recovery
    如何制定目标
    Saliency Map 最新综述
    计算机视觉模式识别重要会议杂志
  • 原文地址:https://www.cnblogs.com/wangxiaodai/p/9766523.html
Copyright © 2011-2022 走看看