zoukankan      html  css  js  c++  java
  • LCA【p2912】 牧场散步 (USACO08OCT)

    z

    你没有发现两个字里的blog都不一样嘛 qwq

    题目描述-->p2912 牧场散步

    题意概括

    给定一个,给你Q个询问,每次询问输入一个二元组((x,y)),要求求出((x,y))的距离.

    明显带权lca.

    这里写一下递推式

    [f[u][i]=f[f[u][i-1]][i-1] ]

    [gw[u][i]=gw[f[u][i-1]][i-1]+gw[u][i-1] ]

    定义:

    (f[u][i])代表(u)向上跳(2^i)步到达的节点.

    (gw[u][i])代表(u)向上跳(2^i)步到达的节点的边权和.

    为什么(f[u][i]=f[f[u][i-1]][i-1])

    我们从(u)到达(f[u][i])需要(2^i)步,而到达(f[u][i-1])需要(2^{i-1})步,再从这个位置跳(2^{i-1})步,的话就到达了(f[u][i])

    [2^{i-1}+2^{i-1}=2*2^{i-1}=2^{i} ]

    又因为我们处理(f[u][i-1])一定比处理(f[u][i])要早,所以这样转移即可.

    初始化

    f[u][0]=fa;
    gw[u][0]=edge[i].w;//即连向u的边权.
    

    然后这样这个题就变成了裸的带权lca问题 qwq.

    ---------------------代码---------------------

    #include<bits/stdc++.h>
    #define R register
    #define N 1008
    using namespace std;
    inline void in(int &x)
    {
    	int f=1;x=0;char s=getchar();
    	while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
    	while(isdigit(s)){x=x*10+s-'0';s=getchar();}
    	x*=f;
    }
    int n,head[N],tot,m;
    int depth[N],f[N][18],gw[N][18];
    struct cod{int u,v,w;}edge[N<<1+8];
    inline void add(int x,int y,int z)
    {
    	edge[++tot].u=head[x];
    	edge[tot].v=y;
    	edge[tot].w=z;
    	head[x]=tot;
    }
    void dfs(int u,int fa,int dis)
    {
    	depth[u]=depth[fa]+1;
    	f[u][0]=fa;gw[u][0]=dis;
    	for(R int i=1;(1<<i)<=depth[u];i++)
    		f[u][i]=f[f[u][i-1]][i-1],
    		gw[u][i]=gw[f[u][i-1]][i-1]+gw[u][i-1];
    	for(R int i=head[u];i;i=edge[i].u)
    	{
    		if(edge[i].v==fa)continue;
    		dfs(edge[i].v,u,edge[i].w);
    	}
    }
    inline int lca(int x,int y)
    {
    	if(depth[x]>depth[y])swap(x,y);
    	int ans=0;
    	for(R int i=17;i>=0;i--)
    		if(depth[y]-(1<<i)>=depth[x])
    			ans+=gw[y][i],y=f[y][i];
    	if(x==y)return ans;
    	for(R int i=17;i>=0;i--)
    	{
    		if(f[x][i]==f[y][i])continue;
    		ans+=gw[x][i]+gw[y][i];
    		y=f[y][i],x=f[x][i];
    	}
    	return (ans+gw[x][0]+gw[y][0]);
    }
    int main()
    {
    	in(n),in(m);
    	for(R int i=1,x,y,z;i<n;i++)
    	{
    		in(x),in(y),in(z);
    		add(x,y,z);add(y,x,z);
    	}
    	dfs(1,0,0);
    	for(R int x,y;m;m--)
    	{
    		in(x),in(y);
    		printf("%d
    ",lca(x,y));
    	}
    }
    
  • 相关阅读:
    Crazypony四轴飞行器代码框架
    Python中 sys.argv[]的用法简明解释
    详解STM32的PWM输出及频率和脉宽(占空比)的计算——寄存器配置六步曲!(转)
    jquery——所有版本下载
    jsop跨域请求方式--及中文乱码解决方案
    js ---任何浏览器关闭当前网页的代码
    jquery ajax跨域请求 IE9及以下不支持---调试
    poi---Excel导入数据-ClassNotFoundException
    ajax获取json数据为undefined--原因解析
    可变参数 / 枚举--详解
  • 原文地址:https://www.cnblogs.com/-guz/p/9709000.html
Copyright © 2011-2022 走看看