ural 1750 Tree 2(树的直径 + 倍增)
来源:互联网 发布:centos 6.8 安装pptp 编辑:程序博客网 时间:2024/05/17 08:10
Tree 2
Time Limit: 1000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u
[Submit] [Go Back] [Status]
Description
Consider a tree consisting of n vertices. A distance between two vertices is the minimal number of edges in a path connecting them. Given a vertex vi and distance di find a vertex ui such that distance between viand ui equals to di.
Input
The first line contains the number of vertices n (1 ≤ n ≤ 20000) and the number of queries q (1 ≤ q ≤ 50000) . Each of the following n − 1 lines describes an edge and contains the numbers of vertices connected by this edge. Vertices are numbered from 1 to n. The next q lines describe the queries. Each query is described by a line containing two numbers vi (1 ≤ vi ≤ n) and di (0 ≤ di ≤ n) .
Output
You should output q lines. The i-th line should contain a vertex number ui, the answer to the i-th query. If there are several possible answers, output any of them. If there are no required vertices, output 0 instead.
Sample Input
input
output
9 101 81 51 42 72 53 65 96 95 48 14 32 49 31 15 23 56 47 3
0123456789
题意:给出一棵树,树上两点的距离为两点路径上的边数,有q个询问,每个询问u d,要求出与u相距为d的任意一个结点。
思路:先求树的直径,得到直径上的两端点,分别以这两个端点为根能构造出两棵新的树,与任意一个点u距离为d的结点v可以在其中一棵树上通过倍增来求出。
AC代码:
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <cmath>#include <vector>#include <algorithm>#define ll long longusing namespace std;const int maxn = 20005;const int INF = 1e9;int n, q;vector<int> G[maxn];int to[maxn];int dis[2][maxn], fa[maxn][2], anc[maxn][30][2];bool vis[maxn];int bfs(int s, int k){ queue<int> Q; memset(vis, 0, sizeof(vis)); memset(dis[k], 0, sizeof(dis[k])); vis[s] = 1; Q.push(s); int idx = s, Max = -1; while(!Q.empty()) { int u = Q.front(); Q.pop(); if(dis[k][u] > Max) { Max = dis[k][u]; idx = u; } for(int i = 0; i < (int) G[u].size(); i++) { int v = G[u][i]; if(vis[v]) continue; vis[v] = true; dis[k][v] = dis[k][u] + 1; fa[v][k] = u; Q.push(v); } } for(int i = 1; i <= n; i++) to[i] = max(to[i], dis[k][i]); return idx;}void init(){ for(int k = 0; k < 2; k++) { for(int i = 1; i <= n; i++) { anc[i][0][k] = fa[i][k]; for(int j = 1; (1 << j) < n; j++) anc[i][j][k] = -1; } for(int j = 1; (1 << j) < n; j++) for(int i = 1; i <= n; i++) if(anc[i][j - 1][k] != -1) { int a = anc[i][j - 1][k]; anc[i][j][k] = anc[a][j - 1][k]; } }}int query(int k, int u, int d){ if(d == 0) return u; if(d == 1) return anc[u][0][k]; int log = 1; for(; (1 << log) <= d; log++); log--; for(int i = log; i >= 0; i--) { if(d >= (1 << i)) { d -= (1 << i); u = anc[u][i][k]; } if(d == 0) return u; } return 0;}int main(){ int a, b; while(~scanf("%d%d", &n, &q)) { for(int i = 1; i <= n; i++) G[i].clear(); for(int i = 0; i < n - 1; i++) { scanf("%d%d", &a, &b); G[a].push_back(b); G[b].push_back(a); } memset(to, 0, sizeof(to)); int s = bfs(1, 0); int t = bfs(s, 1); bfs(t, 0); init(); while(q--) { scanf("%d%d", &a, &b); if(to[a] < b) { puts("0"); continue; } if(dis[0][a] > dis[1][a]) printf("%d\n", query(0, a, b)); else printf("%d\n", query(1, a, b)); } } return 0;}
0 0
- ural 1750 Tree 2(树的直径 + 倍增)
- URAL 1752 Tree 2 树的直径与倍增
- URAL 1752 Tree 2(树的直径+RMQ)
- ural1752找树上距某个点某距离的点(树的直径+倍增)
- 避难向导 树的直径 树上倍增 二分答案
- LightOJ1094Farthest Nodes in a Tree(BFS+树的直径)
- Farthest Nodes in a Tree(树的直径)
- Farthest Nodes in a Tree(树的直径)
- Codeforces-734E Anton and Tree(树的直径)
- 543. Diameter of Binary Tree (二叉树的直径)
- [Codeforces734E]Anton and Tree 树的直径
- 树直径、二叉树直径 Tree diameter (Longest path in an undirected tree)
- 2016.10.27 Tayz T3 范围(倍增LCA+伪.树的直径)
- 树上方法总结 LCA 树上倍增 树链剖分 树的直径 重心
- HDU 3534 Tree(dfs统计树的直径的数量)
- ural 1752 Tree 2
- 【二叉树】树的直径【543. Diameter of Binary Tree】
- light oj 1094 Farthest Nodes in a Tree(树的直径模板)
- 写一个方法,此方法可将obj对象中名为propertyName的属性的值设置为value.
- 海报
- 海报详解
- 在泛型为Integer的ArrayList中存放一个String类型的对象。
- 全选,反选,清除
- ural 1750 Tree 2(树的直径 + 倍增)
- HDU4966
- NYOJ题目139我排第几个(康拓排序)
- Android之高仿微信“首次登录滑动界面”(五)
- HDU4966详解
- Android核心基础——S02E04_android下Junit
- 关于哲学家就餐问题 源代码(linux)
- 关于git远程仓库
- HDU4972