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 ...
随机推荐
- IT从业者的职业道路(从程序员到部门经理) - 项目管理系列文章
十年前,笔者还是一个刚毕业的大学生,对IT业只是停留在学校的编程知识领域.刚出社会,有很多需要学习的地方.在这十年间,笔者经历了程序员,技术经理,项目经理,部门经理等职位.本文就是要说说如何从程序员到 ...
- iPhone 6 被盗记录二【写在315前夕:苹果售后福州直信创邺在没有三包的情况下帮小偷翻新、助力小偷换机销赃!无视王法。让人震惊,痛心,憎恨!消费者很受伤很无奈】
投诉公司: 北京直信创邺数码科技有限公司 标题: 写在315前夕:苹果售后在没有三包的情况下帮小偷翻新.助力小偷换机销赃!无视王法.让人震惊,痛心,憎恨!消费者很受伤很无奈 期望: 还我手机,或者赔 ...
- 基于Windows 10平台的PM2.5检测器制作
本篇文章详细讲解了如何利用SDS011激光式PM2.5传感器.HC-06蓝牙模块和Windows 10设备完成一个简单的PM2.5检测器及其应用程序的开发.该检测器使用蓝牙完成数据输出,方便设备连接, ...
- break、continue、return
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- MongoDB学习笔记~以匿名对象做为查询参数,方便查询子对象
回到目录 对于MongoDB的封装还在继续,对于不断追求简单的编程还在继续,对于喜欢代码的那么感觉,还在继续... 当你的mongo数据表里有子对象时,尤其是列表对象时,使用官方的驱动很是不爽,要记得 ...
- MongoDB学习笔记~批量插入方法的实现
回到目录 批量插入在EF时代大叔就自己封装过,原理是将多次SQL连接和多次向SQL发送的指令减少到1次,或者1000条数据1次,而对于EF产生的语句来说,这无疑是性能高效的,因为EF这边在处理时,每个 ...
- YARN资源调度器
YARN资源调度器 转载请注明出处:http://www.cnblogs.com/BYRans/ 概述 集群资源是非常有限的,在多用户.多任务环境下,需要有一个协调者,来保证在有限资源或业务约束下有序 ...
- On having layout
英文原文在此:http://www.satzansatz.de/cssd/onhavinglayout.htm 介绍 Internet Explorer 中有很多奇怪的渲染问题可以通过赋予其“layo ...
- Spring---BeanFactory
Spring---BeanFactory BeanFactroy是一个Spring容器,用于创建,配置,管理bean,bean之间的依赖关系也有BeanFactory负责维护: BeanFacto ...
- thinkphp
U方法: 模板导入后,先在浏览器执行index.php文件,当出现下图时,框架中的内容才可以出现. 增加admin后台文件夹: 连接数据库:可以使用pdo的方式连接