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从业者的职业规划),介绍了IT从业者的职业规划,对职业路做了规划.然后,又写了文(IT从业者的职业道路(从程序员到部门经理) - 项目管理系列文章),从技术到管理的一个笔者自己 ...
- Oracle 11g数据库详细安装步骤图解
1.先到Oracle官网上下载11g oracle Database 11g 第 2 版 (11.2.0.1.0) 标准版.标准版 1 以及企业版 适用于 Microsoft Windows (x64 ...
- DIV+CSS规范命名大全
网页制作中规范使用DIV+CSS命名规则,可以改善优化功效特别是团队合作时候可以提供合作制作效率,具体DIV CSS命名规则CSS命名大全内容篇. 常用DIV+CSS命名大全集合,即CSS命名规则 D ...
- android android 判断是否滑动
(转自:http://blog.csdn.net/angle_rupert/article/details/6255522) 声明: float x_temp01 = 0.0f; float y_te ...
- Web报表工具FineReport的JS API开发(二)
上次介绍FineReport的JS API中的第一类开发--FR,这次就来介绍一下FS和contentWindow类的开发. 1 FS FS是数据决策系统中的js接口,比如说FS.tabPane.ad ...
- Android UI组件----AppWidget控件入门详解
Widget引入 我们可以把Widget理解成放置在桌面上的小组件(挂件),有了Widget,我们可以很方便地直接在桌面上进行各种操作,例如播放音乐. 当我们长按桌面时,可以看到Widget选项,如下 ...
- BZOJ1055: [HAOI2008]玩具取名[区间DP]
1055: [HAOI2008]玩具取名 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1588 Solved: 925[Submit][Statu ...
- ThinkPHP常用配置路径
//系统常量定义 //去THinkPHP手册中进行查找 echo "<br>"."网站的根目录地址".__ROOT__." "; ...
- [MVC]如何删除文章内容中的图片
1.实现代码 if (!string.IsNullOrWhiteSpace(entity.Content)) { var immgList = TextHelper.GetImgUrlList(ent ...
- BZOJ 4423 【AMPPZ2013】 Bytehattan
Description 比特哈顿镇有n*n个格点,形成了一个网格图.一开始整张图是完整的. 有k次操作,每次会删掉图中的一条边(u,v),你需要回答在删除这条边之后u和v是否仍然连通. Input 第 ...