[LCA][CODEVS 2370]小机房的树

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
void read(int& n)
{
	char c = getchar();
	int tot = 0;
	while(c<'0'||c>'9')c=getchar();
	while(c>='0'&&c<='9')
	{
		tot = tot *10+c-'0';
		c=getchar();
	}
	n = tot;
}
int u,v,w;
int n,m;
const int maxn = 50010;
struct edge
{
	int v,w,next;
}e[maxn*2];
int k=1;
int head[maxn];
void adde(int u,int v,int w)
{
	e[k].v=v;
	e[k].w=w;
	e[k].next=head[u];
	head[u]=k++;
}
int d[maxn];
int f[maxn][22];
long long dis[maxn];
void dfs(int u,int fa)
{
	f[u][0]=fa;
	d[u]=d[fa]+1;
	for(int i=1;i<=20;i++)f[u][i]=f[f[u][i-1]][i-1];
	for(int i=head[u];i!=-1;i=e[i].next)
	{
		if(e[i].v!=fa)
		{
			dis[e[i].v]=dis[u]+e[i].w;
			dfs(e[i].v,u);
		}
	}
}
int lca(int a,int b)
{
	if(d[a]>d[b])swap(a,b);
	for(int i=20;i>=0;i--)
		if(d[a]<=d[b]-(1<<i))
			b = f[b][i];
	if(a==b)return a;
	for(int i=20;i>=0;i--)
	{
		if(f[a][i]==f[b][i])
			continue;
		a=f[a][i];
		b=f[b][i];
	}
	return f[a][0];
}
int main()
{

	memset(head,-1,sizeof(head));
	read(n);
	dis[0]=dis[1]=0;
	for(int i=1;i<n;i++)
	{
		read(u),read(v),read(w);
		u++,v++;
		adde(u,v,w);
		adde(v,u,w);
	}
	dfs(1,0);
	read(m);
	for(int i=1;i<=m;i++)
	{
		read(u),read(v);
		u++,v++;
		int fa = lca(u,v);
		printf("%lld\n",dis[u]+dis[v]-(dis[lca(u,v)])*2);
	}
	return 0;
}

时间: 2024-08-28 01:44:57

[LCA][CODEVS 2370]小机房的树的相关文章

LCA(倍增在线算法) codevs 2370 小机房的树

codevs 2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力.已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计

codevs 2370 小机房的树

2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力.已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到

codevs 2370 小机房的树(LCA)

过了这么长的时间终于开始看LCA了... 有一次训练题卡在LCA当时不会...拖了好久好久...其实现在还是不会... 只会tarjan... 传送门 板子题咯 tarjan的算法就是基于先序遍历的顺序的 #include <bits/stdc++.h> using namespace std; inline int read() { int x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (

【codevs】2370 小机房的树

时间限制: 1 s 空间限制: 256000 KB 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力.已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到这条路,要求你告诉他们最少需要花费多少精力 输入描述 In

2370 小机房的树

题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力.已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到这条路,要求你告诉他们最少需要花费多少精力 输入描述 Input Description 第一行一个n,接下来

小机房的树 codevs 2370

2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力.已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要

小机房的树(codevs 2370)

题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力.已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到这条路,要求你告诉他们最少需要花费多少精力 输入描述 Input Description 第一行一个n,接下来

小机房的树CODEVS 2370

————最近公共祖先和动态规划的完美结合 [题目描述] 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力.已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到这条路,要求你告诉他们最少需要花费多少精力. [输入描述] 第一行一个n,接下来n-1行

[CodeVS2370] 小机房的树 (LCA)

Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力. 已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到这条路,要求你告诉他们最少需要花费多少精力 Input 第一行一个n,接下来n-1行每一行有三个整数u,v, c .表