【codevs1036】商务旅行 LCA 倍增
1036 商务旅行
某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间。
假设有N个城镇,首都编号为1,商人从首都出发,其他各城镇之间都有道路连接,任意两个城镇之间如果有直连道路,在他们之间行驶需要花费单位时间。该国公路网络发达,从首都出发能到达任意一个城镇,并且公路网络不会存在环。
你的任务是帮助该商人计算一下他的最短旅行时间。
输入文件中的第一行有一个整数N,1<=n<=30 000,为城镇的数目。下面N-1行,每行由两个整数a 和b (1<=a, b<=n; a<>b)组成,表示城镇a和城镇b有公路连接。在第N+1行为一个整数M,下面的M行,每行有该商人需要顺次经过的各城镇编号。
在输出文件中输出该商人旅行的最短时间。
5
1 2
1 5
3 5
4 5
4
1
3
2
5
7
题解:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 30005
using namespace std;
int n,m,city[maxn],ans,fist;
int tot,he[maxn],to[maxn*],ne[maxn*];
bool flag[maxn];
int f[][maxn],depth[maxn];
void add(int a,int b)
{
tot++;to[tot]=b;ne[tot]=he[a];he[a]=tot;
}
void build (int x)
{
for (int i=he[x];i;i=ne[i])
if (!flag[to[i]]){
flag[to[i]]=true;
depth[to[i]]=depth[x]+;
f[][to[i]]=x;
build(to[i]);
}
}
void bz()
{
for (int i=;i<=;i++)
for (int j=;j<=n;j++)
f[i][j]=f[i-][f[i-][j]];
}
int lca(int a,int b)
{
int mi=;
if (depth[a]<depth[b]) swap(a,b);
int derta=depth[a]-depth[b];
for (int i=;i<=;i++)
{
if (<<i & derta)
{
mi+=(<<i);
a=f[i][a];
}
}
if (a==b) return mi;
for (int i=;i>=;i--)
{
if (f[i][a]!=f[i][b]) {
a=f[i][a];
b=f[i][b];
int p=(<<i);p*=;//not mi+=(1<<i);mi*=2;
mi+=p;
}
}
a=f[][a];b=f[][b];
mi+=;
return mi;
}
int main()
{
freopen("codevs1036.in","r",stdin);
cin>>n;
for (int i=;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
flag[]=true;
depth[]=;
build();
bz();
cin>>m;cin>>fist;
for (int i=;i<m;i++)
{
int x;scanf("%d",&x);
int y=lca(fist,x);
ans+=y;
fist=x;
}
cout<<ans<<endl;
return ;
}
借鉴方法:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 30005
using namespace std;
int n,m,city[maxn],ans,fist;
int tot,he[maxn],to[maxn*],ne[maxn*];
bool flag[maxn];
int f[][maxn],depth[maxn];
void add(int a,int b)
{
tot++;to[tot]=b;ne[tot]=he[a];he[a]=tot;
}
void build (int x)
{
for (int i=he[x];i;i=ne[i])
if (!flag[to[i]]){
flag[to[i]]=true;
depth[to[i]]=depth[x]+;
f[][to[i]]=x;
build(to[i]);
}
}
void bz()
{
for (int i=;i<=;i++)
for (int j=;j<=n;j++)
f[i][j]=f[i-][f[i-][j]];
}
int lca(int a,int b)
{
//int mi=0;
if (depth[a]<depth[b]) swap(a,b);
int derta=depth[a]-depth[b];
for (int i=;i<=;i++)
{
if (<<i & derta)
{
//mi+=(1<<i);
a=f[i][a];
}
}
if (a==b) return a;
for (int i=;i>=;i--)
{
if (f[i][a]==f[i][b]) continue;
else {
a=f[i][a];
b=f[i][b];
// mi+=(1<<i);mi=(mi<<1);
}
}
// a=f[0][a];b=f[0][b];
//mi+=2;
return f[][a];
}
int main()
{
freopen("codevs1036.in","r",stdin);
cin>>n;
for (int i=;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
flag[]=true;
depth[]=;
build();
bz();
cin>>m;cin>>fist;
for (int i=;i<m;i++)
{
int x;scanf("%d",&x);
ans+=depth[fist]+depth[x]-*depth[lca(fist,x)];
fist=x;
}
cout<<ans<<endl;
return ;
}
【codevs1036】商务旅行 LCA 倍增的更多相关文章
- [codevs1036]商务旅行<LCA:tarjan&倍增>
题目链接:http://codevs.cn/problem/1036/ 今天翻箱倒柜的把这题翻出来做了,以前做的时候没怎么理解,所以今天来重做一下 这题是一个LCA裸题,基本上就把另一道裸题小机房的树 ...
- CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )
CodeVs.1036 商务旅行 ( LCA 最近公共祖先 ) 题意分析 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从 ...
- codevs1036商务旅行(LCA)
1036 商务旅行 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 某首都城市的商人要经常到各城镇去做 ...
- codevs 1036 商务旅行 (倍增LCA)
/* 在我还不知道LCA之前 暴力跑的SPFA 70分 三个点TLE */ #include<iostream> #include<cstdio> #include<cs ...
- [codevs1036] 商务旅行
题目描述 Description 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从首都出发,其他各城镇之间都有道路连接,任 ...
- 倍增法-lca codevs 1036 商务旅行
codevs 1036 商务旅行 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 某首都城市的商人要经常到各城镇去做生意 ...
- C++之路进阶——codevs1036(商务旅行)
1036 商务旅行 题目描述 Description 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从首都出发,其他各城镇 ...
- 【codevs2370】小机房的树 LCA 倍增
2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0 ...
- LCA——倍增求解
LCA,即最近公共祖先,用于解决树上两点的最近公共祖先问题. ; lca(1,2)=3;(原谅我的绘画水平) LCA的求解有三种算法(我知道的)——tarjan,倍增,线段树(我只会两种),NOIp之 ...
随机推荐
- JQuery $()后面的括号里的内容什么时候加引号,什么时候不加
一.如果是已经声明存在的变量或者对象,就不用加引号. 比如var name=document.getElementById("name"); $(name)或者$(this). 二 ...
- Android星星评分控件RatingBar的使用
在Android的开发中,有一个叫做评分控件RatingBar,我们可以使用该控件做等级划分.评分等作用,星星形状显示,也可以半星级别,我们来看一下评分控件如何使用. 布局文件中定义控件以及属性,这里 ...
- hadoop 入门实例【转】
原文链接:http://www.cnblogs.com/xia520pi/archive/2012/06/04/2534533.html 1.数据去重 "数据去重"主要是为了掌握 ...
- 启动eclipse说在sdk目录下的platforma-tools下面找不到adb.exe
adb是什么?adb有什么用?adb工具如何用? 是用来管理模拟器和真机的通用调试工具,该工具功能强大,直接打开cmd即可使用adb命令,adb的全称为Android Debug Bridge,是 ...
- Falcon:三代reads比对组装工具箱
主页:github: PacificBiosciences/FALCON 简介 Falcon是一组通过快速比对长reads,从而来consensus和组装的工具. Falcon工具包是一组简单的代码集 ...
- JSP Scripting Element
There are five different types of scripting elements Scripting Element Example Comment <%-- comme ...
- mac air/pro 启用三指拖动手势
mac air/pro 启用三指拖动手势 一直以来用mac触控版丰富的手势来完成日常的工作,非常的效率和方便! 今天重新安装了系统发面三指拖动不好用了! 仔细查看了 设置--触控板 里面的各种选择尝试 ...
- 资源 之 4.3 访问Resource(拾壹)
4.3.1 ResourceLoader接口 ResourceLoader接口用于返回Resource对象:其实现可以看作是一个生产Resource的工厂类. public interface Re ...
- HTML CSS + DIV实现局部布局
HTML CSS + DIV实现局部布局 HTML CSS + DIV实现局部布局 1.本章教大家掌握2种布局方式: 1)顶部导航菜单布局,效果图: 2)购物版块布局,效果图: 2.技术目标: 使用d ...
- 滚动条--nicescroll插件(兼容各种浏览器,低至IE5)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...