zoukankan      html  css  js  c++  java
  • BZOJ 1602: [Usaco2008 Oct]牧场行走


    题目


    1602: [Usaco2008 Oct]牧场行走

    Time Limit: 5 Sec  Memory Limit: 64 MB

    Description

    N头牛(2<=n<=1000)别人被标记为1到n,在同样被标记1到n的n块土地上吃草,第i头牛在第i块牧场吃草。 这n块土地被n-1条边连接。 奶牛可以在边上行走,第i条边连接第Ai,Bi块牧场,第i条边的长度是Li(1<=Li<=10000)。 这些边被安排成任意两头奶牛都可以通过这些边到达的情况,所以说这是一棵树。 这些奶牛是非常喜欢交际的,经常会去互相访问,他们想让你去帮助他们计算Q(1<=q<=1000)对奶牛之间的距离。

    Input

    *第一行:两个被空格隔开的整数:N和Q

     *第二行到第n行:第i+1行有两个被空格隔开的整数:AI,BI,LI

    *第n+1行到n+Q行:每一行有两个空格隔开的整数:P1,P2,表示两头奶牛的编号。

    Output

    *第1行到第Q行:每行输出一个数,表示那两头奶牛之间的距离。

    Sample Input

    4 2
    2 1 2
    4 3 2
    1 4 3
    1 2
    3 2

    Sample Output

    2
    7

    题解


    这题就是一个裸的LCA,值得高兴的是我竟然是写了一遍之后调都没调直接交就A掉了,好开心~


    代码


    /*Author:WNJXYK*/
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<map>
    using namespace std;
    
    #define LL long long
    
    inline void swap(int &x,int &y){int tmp=x;x=y;y=tmp;}
    inline void swap(LL &x,LL &y){LL tmp=x;x=y;y=tmp;}
    inline int remin(int a,int b){if (a<b) return a;return b;}
    inline int remax(int a,int b){if (a>b) return a;return b;}
    inline LL remin(LL a,LL b){if (a<b) return a;return b;}
    inline LL remax(LL a,LL b){if (a>b) return a;return b;}
    
    int ans[1005][20];
    int dep[1005];
    struct Edge{
    	int u,v;
    	int l;
    	int nxt;
    	Edge(){}
    	Edge(int a,int b,int c,int d){u=a;v=b;l=c;nxt=d;}
    }; 
    Edge e[5005];
    int head[1005];
    int nume=0;
    bool visited[1005];
    int dist[1005];
    
    inline void addEdge(int x,int y,int c){
    	e[++nume]=Edge(x,y,c,head[x]);
    	head[x]=nume;
    	e[++nume]=Edge(y,x,c,head[y]);
    	head[y]=nume;
    }
    
    void dfs(int x,int depth,int dists){
    	visited[x]=true;
    	dep[x]=depth;
    	dist[x]=dists;
    	for (int i=1;i<=10;i++){
    		ans[x][i]=ans[ans[x][i-1]][i-1];
    	}
    	for (int i=head[x];i;i=e[i].nxt){
    		int g=e[i].v;
    		if (visited[g]==false){
    			ans[g][0]=x;
    			dfs(g,depth+1,dists+e[i].l);
    		}
    	}
    }
    
    inline void swim(int &x,int h){
    	for (int i=0;h;i++){
    		if (h&1) x=ans[x][i];
    		h/=2;
    	}
    }
    
    inline int lca(int x,int y){
    	if (dep[x]<dep[y])swap(x,y);
    	swim(x,dep[y]-dep[x]);
    	if (x==y) return x;
    	for (;;){
    		int index=0;
    		for (;ans[x][index]!=ans[y][index];index++);
    		if (index==0) return ans[x][0];
    		x=ans[x][index-1];
    		y=ans[y][index-1];
    	}
    }
    
    int n,Q;
    int main(){
    	scanf("%d%d",&n,&Q);
    	for (int i=1;i<=n-1;i++){
    		int x,y,c;
    		scanf("%d%d%d",&x,&y,&c);
    		addEdge(x,y,c);
    	}
    	ans[1][0]=1;
    	dfs(1,1,0);
    	for (int i=1;i<=Q;i++){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		int lc=lca(x,y);
    		printf("%d
    ",dist[x]+dist[y]-dist[lc]*2);
    	}
    	return 0;
    }
    




  • 相关阅读:
    设计模式(二十)---迭代器模式
    设计模式(十九)---观察者模式
    设计模式(十八)---模板方法模式
    设计模式(十七)---策略模式
    ElasticSearch 安装
    MongoDB进击 Linux单机安装
    List集合去除重复对象。。。记录一下
    Springboot整合mybatisPlus实现分页
    git记录
    Springboot异常处理errorController
  • 原文地址:https://www.cnblogs.com/WNJXYK/p/4063930.html
Copyright © 2011-2022 走看看