hdoj 2586 How far away ? 【LCA转RMQ入门题】
2015-08-09 11:05
381 查看
How far away ?
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8693 Accepted Submission(s): 3044
Problem Description
There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B"? Usually it hard to answer. But luckily int this
village the answer is always unique, since the roads are built in the way that there is a unique simple path("simple" means you can't visit a place twice) between every two houses. Yout task is to answer all these curious people.
Input
First line is a single integer T(T<=10), indicating the number of test cases.
For each test case,in the first line there are two numbers n(2<=n<=40000) and m (1<=m<=200),the number of houses and the number of queries. The following n-1 lines each consisting three numbers i,j,k, separated bu a single space, meaning that there is a road
connecting house i and house j,with length k(0<k<=40000).The houses are labeled from 1 to n.
Next m lines each has distinct integers i and j, you areato answer the distance between house i and house j.
Output
For each test case,output m lines. Each line represents the answer of the query. Output a bland line after each test case.
Sample Input
2 3 2 1 2 10 3 1 15 1 2 2 3 2 2 1 2 100 1 2 2 1
Sample Output
10 25 100 100
题意:给你一个N个点的树和Q次查询,每次查询问你任意两点间距离。
LCA转RMQ 点这里:点我
思路:<u, v>距离 = dist[ u ] + dist[ v ] - 2 * dist[ LCA(u,v)]。其中dist存储节点到根的距离。
AC代码:注意手动开栈 。。。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <cstring> #include <algorithm> #define MAXN 40000+100 #define MAXM 100000+1000 #define LL long long using namespace std; struct Edge { int from, to, val, next; }; Edge edge[MAXM]; int head[MAXN], edgenum; int vs[MAXN<<1]; int depth[MAXN<<1]; int id[MAXN]; int dfs_clock; int dist[MAXN]; int N, Q; void init() { edgenum = 0; memset(head, -1, sizeof(head)); } void addEdge(int u, int v, int w) { Edge E = {u, v, w, head[u]}; edge[edgenum] = E; head[u] = edgenum++; } void getMap() { int a, b, c; for(int i = 1; i < N; i++) { scanf("%d%d%d", &a, &b, &c); addEdge(a, b, c), addEdge(b, a, c); } } void DFS(int u, int fa, int d) { id[u] = dfs_clock; vs[dfs_clock] = u; depth[dfs_clock++] = d; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(v == fa) continue; dist[v] = dist[u] + edge[i].val; DFS(v, u, d+1); vs[dfs_clock] = u; depth[dfs_clock++] = d; } } void find_depth() { memset(id, 0, sizeof(id)); memset(vs, 0, sizeof(vs)); memset(depth, 0, sizeof(depth)); memset(dist, 0, sizeof(dist)); dfs_clock = 1; DFS(1, -1, 0); } int dp[MAXN<<1][30]; void RMQ_init(int NN) { for(int i = 1; i <= NN; i++) dp[i][0] = i; for(int j = 1; (1<<j) <= NN; j++) { for(int i = 1; i + (1<<j) - 1 <= NN; i++) { int a = dp[i][j-1]; int b = dp[i + (1<<(j-1))][j-1]; if(depth[a] <= depth[b]) dp[i][j] = a; else dp[i][j] = b; } } } int query(int L, int R) { int k = 0; while((1<<(k+1)) <= R-L+1) k++; int a = dp[L][k]; int b = dp[R - (1<<k) + 1][k]; if(depth[a] <= depth[b]) return a; else return b; } int LCA(int u, int v) { int x = id[u]; int y = id[v]; if(x < y) return vs[query(x, y)]; else return vs[query(y, x)]; } void solve() { int a, b; while(Q--) { scanf("%d%d", &a, &b); printf("%d\n", dist[a] + dist[b] - 2 * dist[LCA(a, b)]); } } int main() { int t; scanf("%d", &t); while(t--) { scanf("%d%d", &N, &Q); init(); getMap(); find_depth(); RMQ_init(dfs_clock - 1); solve(); } return 0; }
相关文章推荐
- PyDev for Eclipse 简介
- 关于异常
- [经典算法] 八枚硬币
- 取石子 斐波那契博弈 华为oj
- 黑马程序员——21,字符流FileReader,FileWriter,BufferedWriter,BufferedReader,装饰设计模式,LineNumberReader
- Ubuntu 配置tftp服务
- 一些程序员需要知道的资源
- MySQL的myisam引擎表锁优化
- 并查集详解
- 手机改座机
- linux 线程id 与进程id对应关系
- Spring的基本用法
- 用C#生成KML路径文件(下篇)
- UIViewController——Handling View-Related Notifications(处理与视图相关的通知)
- HDU 4985/BC 7A Little Pony and Permutation
- hdu 5358(尺取法)
- 单例模式
- Hadoop之hive 其他
- SQL创建计算时间函数
- Unity武器系统的优化