zoukankan      html  css  js  c++  java
  • 【CODEVS1036】商务旅行【LCA】

    题目大题:

    题目链接:http://codevs.cn/problem/1036/
    给出一棵树和一些要求按顺序到达的点,一开始在点11,求走完这些点要花费多少(一条边花费11


    思路:

    LCALCA模板题。
    假设现在在点xx,要到达点yy,那么很明显所需要的花费就是dep[x]+dep[y]2×dep[lca(x,y)]dep[x]+dep[y]-2\times dep[lca(x,y)]
    累加即可。
    众所周知,LCALCA时间复杂度O(nlogn)O(nlogn)


    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 30100
    #define LG 20
    using namespace std;
    
    int n,f[N][LG+1],head[N],dep[N],ans,m,tot;
    
    struct edge
    {
        int to,next;
    }e[N*2];
    
    void add(int from,int to)
    {
        e[++tot].to=to;
        e[tot].next=head[from];
        head[from]=tot;
    }
    
    void dfs(int x,int fa)
    {
        f[x][0]=fa;  //f[x][k]表示点x的2^k祖先
        dep[x]=dep[fa]+1;  //深度
        for (int i=1;i<=LG;i++)
         f[x][i]=f[f[x][i-1]][i-1];
        for (int i=head[x];~i;i=e[i].next)
         if (e[i].to!=fa)
          dfs(e[i].to,x);
    }
    
    int lca(int x,int y)
    {
        if (dep[x]<dep[y]) swap(x,y);
        for (int i=LG;i>=0;i--)  //先跳到同一层
         if (dep[f[x][i]]>=dep[y]) x=f[x][i];
        if (x==y) return x;
        for (int i=LG;i>=0;i--)  //一起往上跳
         if (f[x][i]!=f[y][i])
         {
            x=f[x][i];
            y=f[y][i];
         }
        return f[x][0];
    }
    
    int main()
    {
        memset(head,-1,sizeof(head));
        scanf("%d",&n);
        int x,y;
        for (int i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        int now=1;
        dfs(1,0);
        scanf("%d",&m);
        for (int i=1;i<=m;i++)
        {
            scanf("%d",&x);
            ans=ans+dep[now]+dep[x]-2*dep[lca(now,x)];
            now=x;
        }
        printf("%d\n",ans);
        return 0;
    }
    
  • 相关阅读:
    HDU 3033 I love sneakers!
    HDU 1712 ACboy needs your help
    FZU 1608 Huge Mission
    HDU 3394 Railway
    【MySQL】20个经典面试题,全部答对月薪10k+
    mysql故障解决笔记
    mysql 索引类型
    linux禁用锁定和解除解锁用户账号的方法
    Linux服务器制定mysql数据库备份的计划任务
    网站服务器安全防范小知识
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998519.html
Copyright © 2011-2022 走看看