• COGS——T1588. [USACO FEB04]距离咨询


    http://cogs.pro/cogs/problem/problem.php?pid=1588

    ★★   输入文件:dquery.in   输出文件:dquery.out   简单对比
    时间限制:1 s   内存限制:256 MB

    【题目描述】

    农夫约翰有N(2<=N<=40000)个农场,标号1到N。M(2<=M<=40000)条的不同的垂直或水平的道路连结着农场,道路的长度不超过1000.这些农场的分布就像下面的地图一样,图中农场用F1..F7表示:

    每个农场最多能在东西南北四个方向连结4个不同的农场。此外,农场只处在道路的两端。道路不会交叉而且每对农场间有且仅有一条路径。邻居鲍伯要约翰来导航,但约翰丢了农场的地图,他只得从电脑的备份中修复率。每一条道路的信息如下:

        从农场23往南经距离10到达农场17

        从农场1往东经距离7到达农场17

        . . .

    最近美国过度肥胖非常普遍。农夫约翰为了让他的奶牛多做运动,举办了奶牛马拉松。马拉松路线要尽量长。

    奶牛们拒绝跑马拉松,因为她们悠闲的生活无法承受约翰选择的如此长的赛道。因此约翰决心找一条更合理的赛道。他打算咨询你。读入地图之后会有K个问题,每个问题包括2个整数,就是约翰感兴趣的2个农场的编号,请尽快算出这2个农场间的距离。

    【输入格式】

    第1行:两个分开的整数N和M。

    第2到M+1行:每行包括4个分开的内容,F1,F2,L,D分别描述两个农场的编号,道路的长度,F1到F2的方向N,E,S,W。

    第2+M行:一个整数K(1<=K<=10000).

    第3+M到2+M+K行:每行输入2个整数,代表2个农场。

    【输出格式】

    对每个问题,输出单独的一个整数,给出正确的距离。

    【样例输入】

    7 6
    1 6 13 E
    6 3 9 E
    3 5 7 S
    4 1 3 N
    2 4 20 W
    4 7 2 S
    3
    1 6
    1 4
    2 6

    【样例输出】

    13
    3
    36

    【提示】

    农场2到农场6有20+3+13=36的距离。

    【来源】

    Brian Dean,2004

    USACO 2004 February Contest Green Problem 3 Distance Queries

    方向 没用

    裸最短路 超时

    用dis[i]记录i到根的距离,ans=dis[u]+dis[v]-2*dis[lca[u,v]] 画个图就能看出来了

    模板题

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <queue>
     5 
     6 using namespace std;
     7 
     8 const int N(40000+15);
     9 int n,m,u,v,w,k;
    10 char ch;
    11 
    12 int head[N],sumedge,cnt;
    13 struct Edge
    14 {
    15     int u,v,w,next;
    16     Edge(int u=0,int v=0,int next=0,int w=0):
    17         u(u),v(v),next(next),w(w){}
    18 }edge[N<<1],e[N<<1];
    19 void Insert(int u,int v,int w)
    20 {
    21     edge[++sumedge]=Edge(u,v,head[u],w);
    22     head[u]=sumedge;
    23 }
    24 
    25 int size[N],deep[N],top[N],dad[N],dis[N];
    26 void DFS(int x)
    27 {
    28     size[x]=1; deep[x]=deep[dad[x]]+1;
    29     for(int i=head[x];i;i=edge[i].next)
    30     {
    31         int to=edge[i].v;
    32         if(dad[x]==to) continue;
    33         dad[to]=x;dis[to]+=dis[x]+edge[i].w;DFS(to);size[x]+=size[to];
    34     }
    35 }
    36 void DFS_(int x)
    37 {
    38     int t=0; if(!top[x]) top[x]=x;
    39     for(int i=head[x];i;i=edge[i].next)
    40     {
    41         int to=edge[i].v;
    42         if(dad[x]!=to&&size[t]<size[to]) t=to;
    43     }
    44     if(t) top[t]=top[x],DFS_(t);
    45     for(int i=head[x];i;i=edge[i].next)
    46     {
    47         int to=edge[i].v;
    48         if(dad[x]!=to&&to!=t) DFS_(to);
    49     }
    50 }
    51 int LCA(int x,int y)
    52 {
    53     for(;top[x]!=top[y];x=dad[top[x]])
    54         if(deep[top[x]]<deep[top[y]]) swap(x,y);        
    55     return deep[x]<deep[y]?x:y;
    56 }
    57 
    58 int main()
    59 {
    60     freopen("dquery.in","r",stdin);
    61     freopen("dquery.out","w",stdout);
    62     
    63     scanf("%d%d",&n,&m);
    64     for(;m;m--)
    65     {
    66         scanf("%d%d%d %c",&u,&v,&w,&ch);
    67         e[++cnt].u=u;e[cnt].v=v;e[cnt].w=w;
    68         Insert(u,v,w);Insert(v,u,w);
    69     }
    70     DFS(1);DFS_(1);
    71     scanf("%d",&k);
    72     for(;k;k--)
    73     {
    74         scanf("%d%d",&u,&v);
    75         printf("%d
    ",dis[u]+dis[v]-(dis[LCA(u,v)]<<1));
    76     }
    77     return 0;
    78 }
    ——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
  • 相关阅读:
    CControlLayer
    CBiontCache
    CHero
    CWidgetMgr---cpp
    CWidgetMgr---H
    CXAnimation类
    CXAnimation.h动画类
    CXCommon.h工具类
    【leetcode】441. Arranging Coins
    【linux基础】关于ARM板子使用O3编译选项优化
  • 原文地址:https://www.cnblogs.com/Shy-key/p/6936544.html
Copyright © 2020-2023  润新知