zoukankan      html  css  js  c++  java
  • Vijos——T1406 拉力赛

    https://vijos.org/p/1460

    描述

    车展结束后,游乐园决定举办一次盛大的山道拉力赛,平平和韵韵自然也要来参加大赛。

    赛场上共有n个连通的计时点,n-1条赛道(构成了一棵树)。每个计时点的高度都不相同(父结点的高度必然大于子结点),相邻计时点间由赛道相连。由于马力不够,所以韵韵的遥控车只能从高处驶向低处。而且韵韵的车跑完每条赛道都需花费一定的时间。

    举办方共拟举办m个赛段的比赛,每次从第u个计时点到第v个计时点,当然其中有不少比赛韵韵的遥控车是不能参加的(因为要上坡)。平平想知道他能参加多少个赛段的比赛,并且想知道他完成这些赛段的总用时。

    赛道皆为单向。

    格式

    输入格式

    第一行两个整数n,m。

    接下来n-1行每行3个整数a、b、t。

    表示韵韵的遥控车可以花t秒从第a个计时点到第b个计时点。

    接下来m行每行2个整数u、v,意义如描述所示。

    输出格式

    第一行输出一个正整数,表示能参加的赛段数。

    第二行输出一个正整数,表示总用时。

    样例1

    样例输入1

    6 2
    1 2 1
    2 4 1
    2 5 1
    5 6 1
    1 3 1
    2 6
    4 5
    

    样例输出1

    1
    2
    

    限制

    各个测试点1s

    提示

    第一个计时点的高度是最高的;
    u≠v;
    对于50%的数据 n≤1000 m≤1000;
    对于100%的数据 n≤10000 m≤100000;
    答案小于2^64。

    来源

    f1zsy birdor

    按标签就开始码,结果~LCA 60~

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstdio>
     4 
     5 using namespace std;
     6 
     7 #define LL long long
     8 
     9 const int N(100000+15);
    10 LL n,m,u,v,w;
    11 
    12 LL head[N],sumedge;
    13 struct Edge
    14 {
    15     LL u,v,w,next;
    16     Edge(LL u=0,LL v=0,LL next=0,LL w=0):
    17         u(u),v(v),next(next),w(w){}
    18 }edge[N];
    19 void ins(LL u,LL v,LL w)
    20 {
    21     edge[++sumedge]=Edge(u,v,head[u],w);
    22     head[u]=sumedge;
    23 }
    24 
    25 LL dis[N],size[N],deep[N],dad[N],top[N];
    26 void DFS(LL 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         LL v=edge[i].v;
    32         if(dad[x]!=v)
    33         {
    34             dad[v]=x;
    35             dis[v]=dis[x]+edge[i].w,
    36             DFS(v),size[x]+=size[v];
    37         }            
    38     }
    39 }
    40 
    41 void DFS_(LL x)
    42 {
    43     LL t=0; if(!top[x]) top[x]=x;
    44     for(int i=head[x];i;i=edge[i].next)
    45     {
    46         LL v=edge[i].v;
    47         if(dad[x]!=v&&size[t]<size[v]) t=v;
    48     }
    49     if(t) top[t]=top[x],DFS_(t);
    50     for(int i=head[x];i;i=edge[i].next)
    51     {
    52         LL v=edge[i].v;
    53         if(dad[x]!=v&&t!=v) DFS_(v);
    54     }
    55 }
    56 
    57 LL LCA(LL x,LL y)
    58 {
    59     for(;top[x]!=top[y];x=top[dad[x]])
    60         if(deep[top[x]]<deep[top[y]]) swap(x,y);
    61     return deep[x]<deep[y]?x:y;
    62 }
    63 
    64 LL ansnum,anstim;
    65 
    66 int main()
    67 {
    68     cin>>n>>m;
    69     for(int i=1;i<n;i++)
    70         cin>>u>>v>>w,ins(u,v,w),ins(v,u,w);
    71     DFS(1);DFS_(1);
    72     for(;m;m--)
    73     {
    74         cin>>u>>v;
    75         if(u==LCA(u,v))
    76             ansnum++,anstim+=dis[v]-dis[u];
    77     }
    78     cout<<ansnum<<endl<<anstim;
    79     return 0;
    80 }
    AWWAWAAAWA

    然后看题解,用sta记录点的先序遍历,ove记录后序遍历,

    如果sta[u]<sta[v]&&ove[u]>ove[v]就说明u是v的祖先~

     1 #include <iostream>
     2 #include <cstdio>
     3 
     4 using namespace std;
     5 
     6 const int M(100000+15);
     7 int n,m,u,v,ansnum;
     8 long long w,anstim;
     9 
    10 int head[M],sumedge;
    11 struct Edge
    12 {
    13     int u,v,next,dis;
    14     long long w;
    15     Edge(int u=0,int v=0,int next=0,int dis=0):
    16         u(u),v(v),next(next),dis(dis){}
    17 }edge[M];
    18 void ins(int u,int v,int w)
    19 {
    20     edge[++sumedge]=Edge(u,v,head[u],w);
    21     head[u]=sumedge;
    22 }
    23 
    24 int dis[M],sta[M],ove[M],tim;
    25 void DFS(int now,int val)
    26 {
    27     sta[now]=++tim; dis[now]=val;
    28     for(int i=head[now];i;i=edge[i].next)
    29         DFS(edge[i].v,val+edge[i].dis);
    30     ove[now]=++tim;
    31 }
    32 
    33 int main()
    34 {
    35     scanf("%d%d",&n,&m);
    36     for(int i=1;i<n;i++)
    37         scanf("%d%d%I64d",&u,&v,&w),ins(u,v,w);
    38     DFS(1,0);
    39     for(;m;m--)
    40     {
    41         scanf("%d%d",&u,&v);
    42         if(sta[u]<sta[v]&&ove[u]>ove[v])
    43             ansnum++,anstim+=dis[v]-dis[u];
    44     }
    45     cout<<ansnum<<endl<<anstim;
    46     return 0;
    47 }
    ——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
  • 相关阅读:
    python模块整理2-sys模块 分类: python Module 2013-09-13 16:49 563人阅读 评论(0) 收藏
    sys常用模块小探 分类: python Module 2013-09-13 16:42 339人阅读 评论(0) 收藏
    先执行linux的clear清屏命令,再执行其他操作 分类: python 小练习 2013-09-13 11:23 441人阅读 评论(0) 收藏
    MySQL 解决ERROR 1045 (28000): Access deniedfor user datam@localhost (using password: YES)的问题 分类: database 2013-09-12 15:52 402人阅读 评论(0) 收藏
    函数名function是一个数据类型,可以赋值 分类: python基础学习 2013-09-12 11:01 366人阅读 评论(0) 收藏
    解决 mysql error: Failed dependencies: 错误 分类: database 2013-09-11 11:23 772人阅读 评论(0) 收藏
    Java之wait()/sleep()和notify()/notifyAll()
    Java之数据流DataInput(Output)Stream 和 字节数组流 ByteArrayInput(Output) Stream的嵌套
    Eclipse的简易教程
    JAVA中的反射机制
  • 原文地址:https://www.cnblogs.com/Shy-key/p/6955139.html
Copyright © 2011-2022 走看看