bzoj1602 [Usaco2008 Oct]牧场行走

来源:互联网 发布:js escape 16进制 编辑:程序博客网 时间:2024/05/22 05:27

没什么好说的,裸树上点对距离,用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]);    }}
0 0