【LCA求最短距离】hdu 2586 How far away ?
来源:互联网 发布:cf刷枪软件永久 编辑:程序博客网 时间:2024/06/05 07:15
How far away ?
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 18117 Accepted Submission(s): 7036
Total Submission(s): 18117 Accepted Submission(s): 7036
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.
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
23 21 2 103 1 151 22 32 21 2 1001 22 1
Sample Output
1025100100
这个题比普通的LCA只多了一个求距离,然后就把我华丽丽的困住了==
当然了,我用的LCA是离线版的并查集那种模板是邝斌的那种,
LCA 不难理解,就是dfs树+并查集 ,但是距离加在哪里??
机智如我想到了在递归的时候求~然而写进去还找错位置了,
原因在于应该写成dis[v]=dis[u]+edge[i].len;而不是dis[v]+=edge[i].len;
然后就是距离的求法dis[u] + dis[v] - 2 * dis[ans(u, v)]
#include <iostream>#include <stdio.h>#include <algorithm>#include <string.h>using namespace std;const int maxn = 40005; //顶点数const int maxq = 205; //最多查询次数,根据题目而定,本题中其实每组数据只有一个查询.//并查集int f[maxn];//根节点int find(int x){ if (f[x] == -1) { return x; } return f[x] = find(f[x]);}void unite(int u, int v){ int x = find(u); int y = find(v); if (x != y) { f[x] = y; }}//并查集结束bool vis[maxn];//节点是否访问int ancestor[maxn];//节点i的祖先struct Edge{ int to, next, len;} edge[maxn * 2];int head[maxn], tot;void addedge(int u, int v, int length) //邻接表头插法加边{ edge[tot].to = v; edge[tot].len = length; // printf("%d ",length); edge[tot].next = head[u]; head[u] = tot++;}struct Query{ int q, next; int index;//查询编号,也就是输入的顺序} query[maxq * 2];int ans[maxn * 2]; //存储每次查询的结果,下表0~Q-1,其实应该开maxq大小的。int h[maxn], tt;int Q;//题目中需要查询的次数int dis[maxn];void addquery(int u, int v, int index) //邻接表头插法加询问{ query[tt].q = v; query[tt].next = h[u]; query[tt].index = index; h[u] = tt++; query[tt].q = u; //相当于两次查询,比如查询 3,5 和5,3结果是一样的,以3为头节点的邻接表中有5,以5为头节点的邻接表中有3 query[tt].next = h[v]; query[tt].index = index; h[v] = tt++;}void init(){ tot = 0; memset(head, -1, sizeof(head)); tt = 0; memset(h, -1, sizeof(h)); memset(vis, 0, sizeof(vis)); memset(f, -1, sizeof(f)); memset(ancestor, 0, sizeof(ancestor)); memset(dis, 0, sizeof(dis));}void LCA(int u){ ancestor[u] = u; vis[u] = true; for (int i = head[u]; i != -1; i = edge[i].next) //和顶点u相关的顶点 { int v = edge[i].to; // printf("%d ",edge[i].len); if (vis[v]) { continue; } //dis[v]+=edge[i].len; dis[v] = dis[u] + edge[i].len; LCA(v); unite(u, v); ancestor[find(u)] = u; //将u的左右孩子的祖先设为u //dis[find(u)]+=dis[u]; } for (int i = h[u]; i != -1; i = query[i].next) //看输入的查询里面有没有和u节点相关的 { int v = query[i].q; if (vis[v]) { ans[query[i].index] = ancestor[find(v)]; } }}bool flag[maxn];//用来确定根节点的int t;int n, u, v, len;int main(){ scanf("%d", &t); while (t--) { scanf("%d%d", &n, &Q); init(); memset(flag, 0, sizeof(flag)); for (int i = 1; i < n; i++) { scanf("%d%d%d", &u, &v, &len); flag[v] = true; //有入度 addedge(u, v, len); addedge(v, u, len); } for (int i = 0; i < Q; i++) { scanf("%d%d", &u, &v); addquery(u, v, i); } int root; for (int i = 1; i <= n; i++) { if (!flag[i]) { root = i; // printf("root=%d ",root); break; } } LCA(root); // for(int i=1;i<=n;i++)printf("%d ",dis[i]); printf("\n"); for (int i = 0; i < Q; i++) { len = dis[query[i << 1].q] + dis[query[i << 1 | 1].q] - dis[ans[i]] * 2; printf("%d\n", len); } } return 0;}
阅读全文
0 0
- 【LCA求最短距离】hdu 2586 How far away ?
- hdu 2586 How far away ? lca求最短路
- hdu2586 How far away ?&& poj1986 Distance Queries(LCA离线求最短距离)
- hdu 2586 How far away ?(LCA 求两点距离)
- hdu 2586 How far away ?(离线tarjan求LCA)
- HDU 2586How far away ? tarjan算法求LCA
- hdu2586How far away ?【LCA tarjan求最短距离】
- HDU 2586 How far away? LCA模板
- HDU 2586 - How far away ? (LCA)
- hdu 2586 How far away ?(LCA)
- HDU--2586--How far away ?【LCA】
- HDU 2586 How far away ?(LCA)
- hdu 2586 How far away ?(LCA)
- hdu 2586 How far away ?(LCA)
- HDU - 2586 How far away ?(LCA)
- How far away ? (hdu 2586 LCA)
- hdu 2586 How far away ?(LCA)
- HDU---2586-How far away(LCA)
- 6.go开源cache2go项目笔记——cache_test文件
- codeforces 863B
- 练习题6
- CodeForces
- LInux中 ~/.profile ~/.bashrc /etc/profile /etc/bashrc 的区别
- 【LCA求最短距离】hdu 2586 How far away ?
- 事务模板 VS 声明式事务
- 525. Contiguous Array
- MOOC清华《VC++面向对象与可视化程序设计》第2章:Windows绘图-例(4)映像模式的使用(二)
- 关于海思HI3531A平台使用std::thread创建线程问题(未解决)
- 7.go开源cache2go项目笔记——benchmark_test文件
- 遇到问题的对策
- 8.go开源cache2go项目笔记——callbacks调用
- XML深度解析