bzoj1602 [Usaco2008 Oct]牧场行走

8 篇文章 0 订阅

没什么好说的,裸树上点对距离,用lca,nlogn求解,结果因为主席树打多了。。统计答案的时候写成f[x]+f[y]-f[lca]-f[fa[lca]],这里存储信息方式不同,一个是点,一个是边,所以不能减去fa,而是2*f[lca]。

#include<cstdio>
#include<algorithm>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=1e5+5;
int head[N*2],next[N*2],val[N*2],go[N*2],tot;
int n,m,q;
int dis[N],dep[N],fa[N][22];
inline void dfs(int x)
{
    fo(i,1,20)fa[x][i]=0;
    fo(i,1,20)fa[x][i]=fa[fa[x][i-1]][i-1];        
    int i=head[x];
    while (i)
    {
        int v=go[i];
        if (v!=fa[x][0])
        {
            fa[v][0]=x;
            dis[v]=dis[x]+val[i];
            dep[v]=dep[x]+1;
            dfs(v);
        }
        i=next[i];
    }       
}
inline int get(int x,int y)
{
    if (dep[x]<dep[y])swap(x,y);
    fd(i,20,0)
    if (dep[fa[x][i]]>=dep[y])x=fa[x][i];
    if (x==y)return x;
    fd(i,20,0)
    if (fa[x][i]!=fa[y][i])
    {
        x=fa[x][i];
        y=fa[y][i];
    }
    return fa[x][0];
}
inline void add(int x,int y,int z)
{
    go[++tot]=y;
    val[tot]=z;
    next[tot]=head[x];
    head[x]=tot;
}
int main()
{
    scanf("%d%d",&n,&q);
    fo(i,1,n-1)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    dep[1]=1;
    dfs(1);
    fo(i,1,q)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        if (x>y)swap(x,y);
        int lca=get(x,y);
        printf("%d\n",dis[x]+dis[y]-2*dis[lca]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值