codevs 1036 商务旅行(Targin求LCA)
Description
某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间。
假设有N个城镇,首都编号为1,商人从首都出发,其他各城镇之间都有道路连接,任意两个城镇之间如果有直连道路,在他们之间行驶需要花费单位时间。该国公路网络发达,从首都出发能到达任意一个城镇,并且公路网络不会存在环。
你的任务是帮助该商人计算一下他的最短旅行时间。
Input
输入文件中的第一行有一个整数N,1<=n<=30 000,为城镇的数目。下面N-1行,每行由两个整数a 和b (1<=a, b<=n; a<>b)组成,表示城镇a和城镇b有公路连接。在第N+1行为一个整数M,下面的M行,每行有该商人需要顺次经过的各城镇编号。
Output
在输出文件中输出该商人旅行的最短时间。
Sample Input
5
1 2
1 5
3 5
4 5
4
1
3
2
5
Sample Output
7
思路
很裸的最近公共祖先的题目,跑一遍spfa记录首都到各个城市的距离,然后找到两点的最近公共祖先,这样就可以根据距离以及最近公共祖先算出两点的最短路了。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 30005;
int tot = 0,road[maxn],dis[maxn],flag[maxn],vis[maxn],head[maxn],fa[maxn],ancestor[maxn];
struct Edge{
int to,next;
}edge[maxn<<1];
int tt = 0,h[maxn],answer[maxn];
struct Query{
int q,next;
int index;
}qry[maxn<<1];
void init(int N)
{
for (int i = 0;i <= N;i++)
{
fa[i] = i;ancestor[i] = 0;
vis[i] = false;
head[i] = h[i] = -1;
}
}
void addedge(int u,int v)
{
edge[tot] = (Edge){v,head[u]};
head[u] = tot++;
}
void add_query(int u,int v,int index)
{
qry[tt] = (Query){v,h[u],index};
h[u] = tt++;
qry[tt] = (Query){u,h[v],index};
h[v] = tt++;
}
void spfa()
{
queue<int>que;
memset(dis,0x3f,sizeof(dis));
memset(flag,false,sizeof(flag));
que.push(1);
dis[1] = 0;
flag[1] = true;
while (!que.empty())
{
int u = que.front();
que.pop();
flag[u] = false;
for (int i = head[u];i != -1;i = edge[i].next)
{
int v = edge[i].to;
if (dis[u] + 1 < dis[v])
{
dis[v] = dis[u] + 1;
if (!flag[v])
{
que.push(v);
flag[v] = true;
}
}
}
}
}
int find(int x)
{
int r = x;
while (r != fa[r]) r = fa[r];
int i = x,j;
while (i != r)
{
j = fa[i];
fa[i] = r;
i = j;
}
return r;
}
void Union(int x,int y)
{
x = find(x),y = find(y);
if (x == y) return;
fa[y] = x;
}
void targin_LCA(int u)
{
ancestor[u] = u;
vis[u] = true;
for (int i = head[u]; i != -1;i = edge[i].next)
{
int v = edge[i].to;
if (vis[v]) continue;
targin_LCA(v);
Union(u,v);
ancestor[find(u)] = u;
}
for (int i = h[u];i != -1;i = qry[i].next)
{
int v = qry[i].q;
if (vis[v])
{
answer[qry[i].index] = ancestor[find(v)];
}
}
}
int main()
{
int N,M,u,v,sum = 0;
scanf("%d",&N);
init(N);
for (int i = 1;i < N;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
spfa();
scanf("%d",&M);
scanf("%d",&road[0]);
for (int i = 1;i < M;i++) scanf("%d",&road[i]),add_query(road[i-1],road[i],i);
targin_LCA(1);
for (int i = 1;i < M;i++)
{
sum += dis[road[i]] + dis[road[i-1]] - 2*dis[answer[i]];
}
printf("%d\n",sum);
return 0;
}
codevs 1036 商务旅行(Targin求LCA)的更多相关文章
- codevs 1036 商务旅行 (倍增LCA)
/* 在我还不知道LCA之前 暴力跑的SPFA 70分 三个点TLE */ #include<iostream> #include<cstdio> #include<cs ...
- 倍增法-lca codevs 1036 商务旅行
codevs 1036 商务旅行 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 某首都城市的商人要经常到各城镇去做生意 ...
- CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )
CodeVs.1036 商务旅行 ( LCA 最近公共祖先 ) 题意分析 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从 ...
- codevs——1036 商务旅行
1036 商务旅行 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 某首都城市的商人要经常 ...
- 【最近公共祖先】【树链剖分】CODEVS 1036 商务旅行
树链剖分求lca模板.O(log(n)),就是不倍增嘛~ #include<cstdio> #include<algorithm> using namespace std; # ...
- CODEVS 1036 商务旅行
题目描述 Description 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从首都出发,其他各城镇之间都有道路连接,任 ...
- 【最近公共祖先】【块状树】CODEVS 1036 商务旅行
在线块状树LCA模板. #include<cstdio> #include<vector> #include<algorithm> #include<cmat ...
- CODEVS——T 1036 商务旅行
http://codevs.cn/problem/1036/ 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Descript ...
- POJ 1330 Nearest Common Ancestors(Targin求LCA)
传送门 Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 26612 Ac ...
随机推荐
- 开发者调试工具Chrome Workspace
Workspace是个什么样的东西呢?他能够在开发者工具中调试修改js或者css同时自动保存文件,能够避免开发人员在工具中调试好,再到编辑器中修改一次代码的重复操作,能够提高一定的效率 配置Chrom ...
- alpha-beta剪枝搜索
•一种基于剪枝( α-βcut-off)的深度优先搜索(depth-first search). •将走棋方定为MAX方,因为它选择着法时总是对其子节点的评估值取极大值,即选择对自己最为有利的着法: ...
- javascript设计模式-策略模式
策略模式笔记 将定义的一组算法封装起来,使其相互之间可以替换. 封装的算法具有一定独立性,不会随客户端变化而变化. 与状态模式异同? 1. 结构上看,它与状态模式很像,也是在内部封 ...
- IP数据报首部解析
IP数据报首部的格式,普通20字节. 4位版本号:当前4--IPv4. 4首部长度:首部长度 8位服务类型TOS: 3bits(优先权)+ 4bits(类型--最小延迟+最大吞吐量+最高可靠性+最小费 ...
- 看 nova-scheduler 如何选择计算节点 - 每天5分钟玩转 OpenStack(27)
本节重点介绍 nova-scheduler 的调度机制和实现方法:即解决如何选择在哪个计算节点上启动 instance 的问题. 创建 Instance 时,用户会提出资源需求,例如 CPU.内存.磁 ...
- android setDestinationInExternalPublicDir 下载到SD卡根目录
一:setDestinationInExternalPublicDir(“Trinea”, “MeiLiShuo.apk”);表示设置下载地址为sd卡的Trinea文件夹,文件名为MeiLiShuo. ...
- 腾讯 Bugly for Xamarin Android 的插件
因为项目中需要异常控制,所以在 gpyer bugly 等 Bug 收集平台中选择,最后选定了 Bugly. 于是将 Bugly 的插件 进行了 Java Binding,打成了 Xamarin 可用 ...
- 装13失败后的逆袭(ComboBox的联动)
当我们在做ComboBox的联动的时候飞一般的敲出自认为完美的代码.在运行的时候突然变得不完美了. 比如: 如果发生了这种情况会不会就卡磁了呢 当然不会作为程序猿的我们考的是我们聪明的大脑,当然会想出 ...
- Unity 下载存档
各种版本的UNITY下载 https://unity3d.com/cn/get-unity/download/archive
- 部署 OpenStack VirtualBox
VirtualBox 中部署 OpenStack 大家新年好,CloudMan 今天给大家带来一件新年礼物. 一直以来大家都反馈 OpenStack 学习有两大障碍:1. 实验环境难搭2. 体系复杂, ...