hdu 2586 How far away ? 【图论-邻接表-图转树-Lca】
来源:互联网 发布:网络直播怎么下载 编辑:程序博客网 时间:2024/05/17 07:16
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
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个房子,这n个房子用n-1条路连接起来,接下了有m次询问,每次询问两个房子a,b之间的距离是多少。
很明显的最近公共祖先问题,先建一棵树,然后求出每一点i到树根的距离dis[i],然后每次询问a,b之间的距离=dis[a]+dis[b]-2*dis[LCA(a,b)];
LCA(a,b)即是a,b的最近公共祖先。。
AC代码1:
# include <stdio.h># include <string.h># include <cmath># include <algorithm>using namespace std;# define MAXN 400005struct EDGE{ int v; int w; int next;}edge[MAXN]; //邻接表存放图结构int tot;int head[MAXN];int vis[MAXN];int pre[MAXN];int depth[MAXN];int dis[MAXN];int parent[MAXN][25];void Init(){ tot = 0; memset(head, -1, sizeof(head));}void Addedge(int u, int v, int w){ edge[tot].v = v; edge[tot].w = w; edge[tot].next = head[u]; head[u] = tot++;}void dfs(int u, int father, int d) //搜索 把图结构装换成树结构{ depth[u] = d; pre[u] = father; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if (v != father) { dis[v] = dis[u] + edge[i].w; dfs(v, u, d+1); } }}void LcaInit(int n){ int i, j; for (j = 0; (1 << j) <= n; j++) { for (i = 1; i <= n; i++) { parent[i][j] = -1; } } for (i = 1; i <= n; i++) { parent[i][0] = pre[i]; } for (j = 1; (1 << j) <= n; j++) { for (i = 1; i <= n; i++) { if (parent[i][j - 1] != -1) { parent[i][j] = parent[parent[i][j - 1]][j - 1]; } } }}int Lca(int a, int b) //求公共祖先{ int i, j; if (depth[a] < depth[b]) { swap(a, b); } for (i = 0; (1 << i) <= depth[a]; i++); i--; for (j = i; j >= 0; j--) { if (depth[a] - depth[b] >= (1 << j)) { a = parent[a][j]; } } if (a == b) { return a; } for (j = i; j >= 0; j--) { if (parent[a][j] != -1 && parent[a][j] != parent[b][j]) { a = parent[a][j]; b = parent[b][j]; } } return pre[a];}int main(void){ int t; int i, j; scanf("%d", &t); while (t--) { int n, m; int u, v, w; scanf("%d %d", &n, &m); Init(); for (int i = 1; i < n; i++) { scanf("%d %d %d", &u, &v, &w); Addedge(u, v, w); Addedge(v, u, w); } dis[1] = 0; dfs(1, -1, 0); LcaInit(n); int ans = 0; for (i = 0; i < m; i++) { scanf("%d %d", &u, &v); ans = dis[u] + dis[v] - 2 * dis[Lca(u, v)]; printf("%d\n", ans); } } return 0;}
AC代码2:
# include <stdio.h># include <string.h># include <cmath># include <vector># include <algorithm>using namespace std;# define MAXN 40005struct node{ int v, w; node(int a = 0, int b = 0){ v = a; w = b; }};vector<node> edge[MAXN]; //使用vector容器存放图结构int vis[MAXN];int pre[MAXN];int depth[MAXN];int dis[MAXN];int parent[MAXN][25];void dfs(int u, int father, int d) //图转树{ depth[u] = d; pre[u] = father; int num = edge[u].size(); for (int i = 0; i < num; i++) { int v = edge[u][i].v; if (v != father) { dis[v] = dis[u] + edge[u][i].w; dfs(v, u, d + 1); } }}void LcaInit(int n){ int i, j; for (j = 0; (1 << j) <= n; j++) { for (i = 1; i <= n; i++) { parent[i][j] = -1; } } for (i = 1; i <= n; i++) { parent[i][0] = pre[i]; } for (j = 1; (1 << j) <= n; j++) { for (i = 1; i <= n; i++) { if (parent[i][j - 1] != -1) { parent[i][j] = parent[parent[i][j - 1]][j - 1]; } } }}int Lca(int a, int b){ int i, j; if (depth[a] < depth[b]) { swap(a, b); } for (i = 0; (1 << i) <= depth[a]; i++); i--; for (j = i; j >= 0; j--) { if (depth[a] - depth[b] >= (1 << j)) { a = parent[a][j]; } } if (a == b) { return a; } for (j = i; j >= 0; j--) { if (parent[a][j] != -1 && parent[a][j] != parent[b][j]) { a = parent[a][j]; b = parent[b][j]; } } return pre[a];}int main(void){ int t; int i, j; scanf("%d", &t); while (t--) { int n, m; int u, v, w; scanf("%d %d", &n, &m); for (i = 1; i <= n; i++) { edge[i].clear(); } for (i = 1; i < n; i++) { scanf("%d %d %d", &u, &v, &w); edge[u].push_back(node(v, w)); edge[v].push_back(node(u, w)); } dis[1] = 0; dfs(1, -1, 0); LcaInit(n); int ans = 0; for (i = 0; i < m; i++) { scanf("%d %d", &u, &v); ans = dis[u] + dis[v] - 2 * dis[Lca(u, v)]; printf("%d\n", ans); } } return 0;}
- 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)
- HDU - 2586 How far away ?(LCA)
- How far away ? (hdu 2586 LCA)
- hdu 2586 How far away ?(LCA)
- HDU---2586-How far away(LCA)
- HDU 2586 How far away ?(LCA)
- HDU 2586How 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 ?【rmq+lca】
- GC参数
- 微服务
- python学习笔记5
- Spring 注解 事务
- FineUI秘密花园(二) — 一切从头开始
- hdu 2586 How far away ? 【图论-邻接表-图转树-Lca】
- 1002. 写出这个数
- 解析客户端请求信息Headers
- 配置angularjs项目运行环境的几个步骤
- Linux进程间通信——使用信号
- $(...).modal is not a function
- org.apache.commons.net.ftp.FTPClient上传下载压缩图片
- js navicator对象、match方法
- 图的连通性问题