vijos p1460——拉力赛

描述

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

赛场上共有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。

LCA,只用记录下deep就可以了,LCA判断x和y的公共祖先是否为x或y若是的话加上时间即可。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 using namespace std;
 6 const int maxn=10005;
 7 int fa[maxn][20],deep[maxn];
 8 int head[maxn],nextn[maxn],tov[maxn],w[maxn];
 9 int pd[maxn];
10 int n,m,tot;int d[maxn];
11 long long t,ans;
12 void go(int x,int y,int z)
13 {
14     tot++;
15     nextn[tot]=head[x];
16     head[x]=tot;
17     tov[tot]=y;
18     w[tot]=z;
19 }
20 
21 void dfs(int x)
22 {
23     int v=head[x];
24     while(v)
25     {
26         if(pd[tov[v]]==false)
27         {
28             fa[tov[v]][0]=x;
29             deep[tov[v]]=deep[x]+1;
30             d[tov[v]]=d[x]+w[v];
31             pd[tov[v]]=true;
32             int ii=0,pos=x;
33             while(fa[pos][ii])
34             {
35                 fa[tov[v]][ii+1]=fa[pos][ii];
36                 pos=fa[pos][ii];        
37                 ii++;
38             }
39             dfs(tov[v]);
40         }
41         v=nextn[v];
42     }
43 }
44 void lca(int x,int y)
45 {
46     if(deep[x]>deep[y])return ;
47     int m=deep[y]-deep[x];
48     int ii=0;
49     int k=y;
50     while(m)
51     {
52         if(m&1)y=fa[y][ii];
53         m=(m>>1);
54         ii++;
55     }
56     if(x!=y)return ;
57     ans++;
58     t+=d[k]-d[x];
59 }
60 int main()
61 {
62     scanf("%d%d",&n,&m);
63     for(int i=1;i<=n-1;i++)
64     {
65         int x,y,z;
66         scanf("%d%d%d",&x,&y,&z);
67         go(x,y,z);
68     }
69     deep[1]=1;pd[1]=true;
70     dfs(1);
71     for(int i=1;i<=m;i++)
72     {
73         int x,y;
74         scanf("%d%d",&x,&y);
75         lca(x,y);
76     }
77     printf("%I64d
",ans);
78     printf("%I64d
",t);
79     return 0;
80 }
 
原文地址:https://www.cnblogs.com/937337156Zhang/p/6052410.html