VIJOS1460拉力赛,最近公共祖先

来源:互联网 发布:emoi软件 编辑:程序博客网 时间:2024/05/22 06:13

一叶落寞,万物失色.

描述

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

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

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

赛道皆为单向。

格式

输入格式

第一行两个整数n,m。

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

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

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

输出格式

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

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

样例1

样例输入1

6 21 2 12 4 12 5 15 6 11 3 12 64 5

样例输出1

12

限制

各个测试点1s

提示

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

题目不难,只需要判断u和v的公共祖先是不是u(保证u,v在同一子树上这样才能保证啦不爬山),然后记录下路径的长度,可以用前缀和优化,要注意下longlong

代码:

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<string>#include<cstdlib>#include<math.h>using namespace std;int read(){    char ch;int s=0,f=1;ch=getchar();    while(ch>'9'||ch<'0'){ if(ch=='-') f*=-1; ch=getchar(); }    while(ch>='0'&&ch<='9') { s=s*10+ch-48; ch=getchar() ;}    return s*f;}struct node {int y,nxt,v;}e[10000*2+10];int head[10005],cnt;void add(int x,int y,int z){  cnt++;  e[cnt].y=y,e[cnt].v=z,e[cnt].nxt=head[x];  head[x]=cnt;}int deep[10000+5];long long dis[10005];int fa[10005][20];int n,m;void init(){    for(int i=1;i<=n;i++)    {        for(int j=0;j<19;j++) fa[i][j]=0;        deep[i]=0,dis[i]=0;    }}void dfs(int x){    for(int i=head[x];i;i=e[i].nxt)    {        int v=e[i].y;        if(!deep[v])        {            deep[v]=deep[x]+1;            dis[v]=dis[x]+e[i].v;            fa[v][0]=x;            dfs(v);        }    }}int lca(int x,int y){    if(deep[x]<deep[y])swap(x,y);    for(int i=19;i>=0;i--)    {        if(deep[fa[x][i]]>=deep[y])        x=fa[x][i];        }    if(x==y)return x;    for(int i=19;i>=0;i--)    if(fa[x][i]!=fa[y][i])    x=fa[x][i],y=fa[y][i];    return fa[x][0];}int main(){n=read(),m=read();for(int i=1;i<n;i++){    int u,v,t;    u=read(),v=read(),t=read();    add(u,v,t),add(v,u,t);}deep[1]=1;dis[1]=0;dfs(1);for(int i=1;i<=19;i++) for(int j=1;j<=n;j++) fa[j][i]=fa[fa[j][i-1]][i-1]; long long ans=0,now=0; for(int i=1;i<=m;i++) {     int u,v;     u=read(),v=read();     if(lca(u,v)==u)     {         ans++;         now+=(dis[v]-dis[u]);     } } printf("%lld\n%lld",ans,now); return 0;}

一叶落寞,万物失色.



0 0
原创粉丝点击