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;
}
一叶落寞,万物失色.
相关文章推荐
- 树上两点的最近公共祖先问题(Least Common Ancestors)
- HDU4547.CD操作——最近公共祖先
- LCA问题(最近公共祖先问题)+ RMQ问题
- Hdu 4547 【最近公共祖先】.cpp
- 最近公共祖先(Least Common Ancestors,LCA)问题详解
- LintCode:最近公共祖先
- 在二叉树中,求任意两个节点的最近公共祖先(遍历的应用算法)
- 【讲解+模板】最近公共祖先(LCA)(倍增)
- 洛谷 P3379 【模板】最近公共祖先(LCA)
- poj 1330 LCA最近公共祖先
- 邦德,白书P345UVa11345(最小生成树,无根树转有根树,最近公共祖先,二进制快速查找)
- hdu 2586 How far away ? 最近公共祖先lca 在线算法(倍增法)/离线算法(Tarjan算法)
- 求树中两个节点的最近公共祖先
- Hihocoder #1067 : 最近公共祖先·二
- HDU 1330 Nearest Common Ancestors(求两个点的最近公共祖先)
- 数据结构作业——sights(最短路/最近公共祖先)
- 【模板】最近公共祖先(LCA)
- 最近公共祖先LCA Tarjan算法
- HiHo 第十三周 #1062 : 最近公共祖先·一 【map】
- 寻找二叉树中两个节点的最近的公共祖先