#USACO 2004 FEB#距离询问(LCA树链问题)
来源:互联网 发布:国外免费网络视频聊天 编辑:程序博客网 时间:2024/05/22 13:20
2684: [USACO 2004 FEB]距离询问
时间限制:1 Sec 内存限制:128 MB题目描述
FJ有N(2 <= N <= 40,000)个农场,编号从1..N。有M(1 <= M < 40,000)条水平或者垂直的道路连接这些农场(1 <= length <= 1000)。下图是有7个农场的例子,括号中的数字表示道路的长度:
F1 --- (13) ---- F6 --- (9) ----- F3 | | (3) | | (7) F4 --- (20) -------- F2 | | | (2) F5 | F7
每个农场最多只与它上、下、左、右的农场相连。任意两个农场之间,只有唯一的一条路径。
现在给出K个询问,形如:X Y,表示请你回答编号为X的农场与编号为Y的农场之间的路径长度
输入
第1行:2个整数 N 和 M,意义如前所述
接下来M行,每行4个变量F1, F2, L, D 描述一条道路, F1 和 F2 是这条道路所连接的两个农场的编号, L 是这条道路的长度, D 是这条道路从F1到F2的方向,即 'N', 'E', 'S', 'W' 这4个字母之一,分别表示北,东,南,西
接下来1行上有1个整数K,表示询问的次数K (1 <= K <= 10,000)
接下来K行,每行2个整数X,Y,表示询问X和Y之间的最短距离
输出
对每个询问,在一个单独的行上,用一个整数回答
样例输入
7 61 6 13 E6 3 9 E3 5 7 S4 1 3 N2 4 20 W4 7 2 S31 61 42 6
样例输出
13336
提示
Farms 2 and 6 are 20+3+13=36 apart.
学长来讲树链问题,首先是基础的倍增LCA
这题很基础,就是求两个点到它们LCA的距离和,随便提一个当做根,注意首先离线出每个点到Root的距离,然后在线查询(否则就T呐)
Code:
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>using namespace std;const int Maxn = 40000;const int Maxm = 40000;const int LOG = 18;struct node{ int v, len, nxt;}edge[Maxm << 1];int N, M, cnt, Root;int fir[Maxn + 5], Dep[Maxn + 5], Dis[Maxn + 5];int f[Maxn + 5][LOG];bool getint(int & num){ char c; int flg = 1; num = 0; while((c = getchar()) < '0' || c > '9'){ if(c == '-') flg = -1; if(c == -1) return 0; } while(c >= '0' && c <= '9') { num = num * 10 + c - 48; if((c = getchar()) == -1) return 0; } num *= flg; return 1;}void addedge(int a, int b, int len){ edge[++ cnt].v = b, edge[cnt].len = len, edge[cnt].nxt = fir[a], fir[a] = cnt;}void Dfs(int x, int fa){ Dep[x] = Dep[fa] + 1; f[x][0] = fa; for(int i = fir[x]; i; i = edge[i].nxt) if(edge[i].v != fa) Dis[edge[i].v] = Dis[x] + edge[i].len, Dfs(edge[i].v, x);}int Get_k(int u, int k){ for(int j = 0; j < LOG; ++ j) if(k & (1 << j)) u = f[u][j]; return u;}int Get_d(int u, int k){ return Get_k(u, Dep[u] - k);}int LCA(int u, int v){ if(Dep[u] > Dep[v]) u = Get_d(u, Dep[v]); else if(Dep[u] < Dep[v]) v = Get_d(v, Dep[u]); if(u == v) return u; for(int j = LOG - 1; j >= 0; -- j) if(f[u][j] != f[v][j]) u = f[u][j], v = f[v][j]; return f[u][0];}int main(){ getint(N), getint(M); int u, v, l, r; for(int i = 1; i <= M; ++ i) getint(u), getint(v), getint(l), addedge(u, v, l), addedge(v, u, l); Root = 1; Dfs(Root, 0); for(int j = 1; j < LOG; ++ j) for(int i = 1; i <= N; ++ i) f[i][j] = f[f[i][j - 1]][j - 1]; getint(M); while(M --){ getint(u), getint(v); r = LCA(u, v); printf("%d\n", Dis[u] - Dis[r] + Dis[v] - Dis[r]); } return 0;}
阅读全文
0 0
- #USACO 2004 FEB#距离询问(LCA树链问题)
- [BZOJ2684][USACO 2004 FEB]距离询问
- BZOJ3364: [Usaco2004 Feb]Distance Queries 距离咨询 LCA
- bzoj 3364: [Usaco2004 Feb]Distance Queries 距离咨询 LCA
- 【结论】【树(LCA)】NKOJ3815 树上的询问
- 树上询问 裸LCA
- USACO 2009 Feb StockMarket
- USACO 2002 Feb CowCycling
- [USACO 2009 Feb] 股票市场
- LCA 多次询问 解法总结
- USACO 2016 Feb Fenced In 最小生成树
- USACO 2010 FEB Silver题解
- [USACO 2014 Feb Silver]scode
- POJ-1330-只询问一次的LCA
- 祖孙询问 纪中3054 LCA
- NOIP级别 祖孙询问 LCA 解题报告
- 图论 tarjan 求 LCA 祖孙询问
- POJ 1987 BZOJ 3365 USACO 2004 Feb Distance Statistics 路程统计 点分治
- java正则表达式
- java动态代理
- 新手 使用eclipse springMVC xml 不提示问题解决方案
- Binwalk:后门(固件)分析利器
- websocket 分布式开发,websocket session不支持序列化,无法存储至radis
- #USACO 2004 FEB#距离询问(LCA树链问题)
- HDU 1874 畅通工程续 <Dijkstra模板题>
- LeetCode 97 Interleaving String(Python详解及实现)
- GridView组件常用属性
- WebView整理
- 软件测试之BUG分析定位概述(转载)
- Qt下载地址
- Azkaban入门篇
- 高并发重复插入数据的场景之一