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 的基础 学习 第六天 基础数据类型的操作方法 字典
    python 的基础 学习 第五天 基础数据类型的操作方法
    python 的基础 学习 第四天 基础数据类型
    ASP.NET MVC 入门8、ModelState与数据验证
    ASP.NET MVC 入门7、Hellper与数据的提交与绑定
    ASP.NET MVC 入门6、TempData
    ASP.NET MVC 入门5、View与ViewData
    ASP.NET MVC 入门4、Controller与Action
    ASP.NET MVC 入门3、Routing
    ASP.NET MVC 入门2、项目的目录结构与核心的DLL
  • 原文地址:https://www.cnblogs.com/Shy-key/p/6955139.html
Copyright © 2011-2022 走看看