zoukankan      html  css  js  c++  java
  • codevs 1036 商务旅行

    时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 钻石 Diamond
    题目描述 Description

    某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间。

    假设有N个城镇,首都编号为1,商人从首都出发,其他各城镇之间都有道路连接,任意两个城镇之间如果有直连道路,在他们之间行驶需要花费单位时间。该国公路网络发达,从首都出发能到达任意一个城镇,并且公路网络不会存在环。

    你的任务是帮助该商人计算一下他的最短旅行时间。

    输入描述 Input Description

    输入文件中的第一行有一个整数N,1<=n<=30 000,为城镇的数目。下面N-1行,每行由两个整数a 和b (1<=ab<=n; a<>b)组成,表示城镇a和城镇b有公路连接。在第N+1行为一个整数M,下面的M行,每行有该商人需要顺次经过的各城镇编号。

    输出描述 Output Description

        在输出文件中输出该商人旅行的最短时间。

    样例输入 Sample Input
    5
    1 2
    1 5
    3 5
    4 5
    4
    1
    3
    2
    5
    样例输出 Sample Output

    7

    数据范围及提示 Data Size & Hint

     

    LCA 

    求上一个地点last到下一地点a的LCA x

    距离等于

    deep[last]+deep[a]-2*deep[x]。

    但是我不明白的是TLE 开大数组就过了 

    屠龙宝刀点击就送

    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #define Max 30000
    
    using namespace std;
    
    struct Edge
    {
        int next,to;
    }edge[Max*3];
    struct point
    {
        int fa,size,chain,deep;
    }p[Max+1000];
    int kk,head[Max*3],cnt,n,m,a;
    void qr(int &x)
    {
        x=0;int f=1;
        char ch=getchar();
        while(ch>'9'||ch<'0')
        {
            if(ch=='-') f=-1;
             ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+(int)ch-48;
            ch=getchar();
        }
        x*=f;
    }
    void add(int u,int v)    
    {
        cnt++;
        edge[cnt].next=head[u];
        edge[cnt].to=v;
        head[u]=cnt;
    }
    void dfs1(int now,int fa)
    {
        int pos=kk++;
        p[now].fa=fa;
        p[now].deep=p[p[now].fa].deep+1;
        for(int i=head[now];i;i=edge[i].next)
        {
            if(edge[i].to==fa) continue;
            dfs1(edge[i].to,now);
        }
        p[now].size=kk-pos;
    }
    void dfs2(int now,int chain)
    {
        int pos=0;
        p[now].chain=chain;
        for(int i=head[now];i;i=edge[i].next)
        {
            if(p[edge[i].to].chain) continue;
            if(p[pos].size<p[edge[i].to].size)
            pos=edge[i].to;
        }
        if(pos) dfs2(pos,chain);
        else return;
        for(int i=head[now];i;i=edge[i].next)
        {
            if(edge[i].to==p[now].fa||edge[i].to==pos) continue;
            dfs2(edge[i].to,edge[i].to);
        }
    }
    int lca(int x,int y)
    {
        while(p[x].chain!=p[y].chain)
        {
            if(p[p[x].chain].deep<p[p[y].chain].deep)
            swap(x,y);
            x=p[p[x].chain].fa;
        }
        return p[x].deep<p[y].deep?x:y;
    }
    int main()
    {
        qr(n);
        int k=n-1;
        for(int a,b;k--;)
        {
            qr(a);qr(b);
            add(a,b);
            add(b,a);
        }
        dfs1(1,0);
        kk=0;dfs2(1,1);
        int v;
        qr(m);    qr(v);
        m-=1;
        int ans=0;
        for(int x,last=v;m--;)
        {
            qr(v);
            x=lca(v,last);
            ans+=p[v].deep+p[last].deep-(2*p[x].deep);
            last=v;
        }
        printf("%d",ans);
        return 0;
    }
    我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。
  • 相关阅读:
    匈牙利算法——S.B.S.
    洛谷P1328 生活大爆炸版石头剪刀布——S.B.S.
    洛谷P1101 单词方阵——S.B.S.
    noip2010提高组3题题解 by rLq
    洛谷P1605 迷宫——S.B.S.
    yii2.0 curd操作
    我常用的linux命令
    常用css
    ln 软链
    crontab下git命令无效
  • 原文地址:https://www.cnblogs.com/ruojisun/p/6561349.html
Copyright © 2011-2022 走看看