您的位置:首页 > 其它

VIJOS1460拉力赛,最近公共祖先

2017-04-14 17:58 281 查看

一叶落寞,万物失色.

描述

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

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

题目不难,只需要判断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;
}
一叶落寞,万物失色.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: