zoukankan      html  css  js  c++  java
  • [codevs2370]小机房的树

    题目大意:给你一棵树,要求两个节点间的最短距离。

    解题思路:求出每个询问的LCA,然后每次用前缀和减一减就得到答案了。我用的是倍增,在DFS的时候顺便求前缀和就行了。

    C++ Code:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using std::swap;
    int a[50000+20];
    struct edge{
    	int dist,next,to;
    }e[50000*2+20];
    int head[50000*2+20],n,m,deep[50000+20],p[50000+20][20],cnt=0;
    void addedge(int x,int y,int c){
    	e[++cnt].to=y;
    	e[cnt].dist=c;
    	e[cnt].next=head[x];
    	head[x]=cnt;
    	e[++cnt].to=x;
    	e[cnt].dist=c;
    	e[cnt].next=head[y];
    	head[y]=cnt;
    }
    void dfs(int u){
    	for(int i=head[u];i;i=e[i].next)
    	if(!deep[e[i].to]){
    		deep[e[i].to]=deep[u]+1;
    		p[e[i].to][0]=u;
    		a[e[i].to]=a[u]+e[i].dist;
    		dfs(e[i].to);
    	}
    }
    int lca(int x,int y){
    	if(deep[x]<deep[y])swap(x,y);
    	int j;
    	for(j=0;(1<<j)<=n;++j);j--;
    	for(int i=j;i>=0;--i)
    	if(deep[p[x][i]]>=deep[y])x=p[x][i];
    	if(x==y)return x;
    	for(int i=j;i>=0;--i)
    	if(p[x][i]!=-1&&p[x][i]!=p[y][i])x=p[x][i],y=p[y][i];
    	return p[x][0];
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<n;++i){
    		int x,y,c;
    		scanf("%d%d%d",&x,&y,&c);
    		addedge(x,y,c);
    	}
    	memset(p,-1,sizeof p);
    	a[0]=0;
    	deep[0]=1;
    	dfs(0);
    	for(int j=1;(1<<j)<=n;++j)
    	for(int i=1;i<=n;i++)
    	if(p[i][j-1]!=-1)p[i][j]=p[p[i][j-1]][j-1];
    	scanf("%d",&m);
    	while(m--){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		printf("%d
    ",a[x]+a[y]-2*a[lca(x,y)]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    1. Deep Q-Learning
    Ⅶ. Policy Gradient Methods
    Ⅴ. Temporal-Difference Learning
    idea在service窗口中显示多个服务
    pycharm下运行flask框架的脚本时报错
    windows下部署 flask (win10+flask+nginx)
    pip install selenium报错解决方法
    pip 及 selenium安装命令
    动作捕捉系统用于模仿学习
    柔性微创手术机器人性能实验验证
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/7183991.html
Copyright © 2011-2022 走看看