POJ - 1330 Nearest Common Ancestors(LCA在线查询)
2015-09-12 17:13
489 查看
题目大意:给你一棵树,要求你输出两个点的LCA
解题思路:模版题
解题思路:模版题
[code]#include <cstdio> #include <cstring> const int MAXNODE = 100010; const int MAXEDGE = 200010; struct Edge { int u, v, next; Edge() {} Edge(int u, int v, int next): u(u), v(v), next(next) {} }; struct ST { Edge edges[MAXEDGE]; int n, m, tot; int head[MAXNODE], depth[MAXNODE], first[MAXNODE], ver[MAXNODE]; int dp[MAXNODE][64]; bool vis[MAXNODE]; void init(int n) { this->n = n; m = tot = 0; memset(head, -1, sizeof(head)); memset(vis, 0, sizeof(vis)); } void AddEdge(int u, int v) { edges[m] = Edge(u, v, head[u]); head[u] = m++; } //ver记录的是第tot个结点是哪个,first记录的是结点u第一次出现的位置,depth记录的是第tot个结点的深度 void dfs(int u, int dep) { vis[u] = true; ver[++tot] = u; first[u] = tot; depth[tot] = dep; for (int i = head[u]; ~i; i = edges[i].next) { int v = edges[i].v; if (!vis[v]) { dfs(v, dep + 1); ver[++tot] = u; depth[tot] = dep; } } } void RMQ() { //dp记录的是下标从i开始,长度为2的j次方这段区间内深度最小的点是ver中的第几个 for (int i = 1; i <= tot; i++) dp[i][0] = i; int a, b; for (int j = 1; (1 << j) <= tot; j++) for (int i = 1; i + (1 << j) - 1 <= tot; i++) { a = dp[i][j - 1]; b = dp[i + (1 << (j - 1))][j - 1]; if (depth[a] < depth[b]) dp[i][j] = a; else dp[i][j] = b; } } void solve(int root) { dfs(root, 1); RMQ(); } //查询区间[x,y]中深度最小的那个数的位置 int Query(int x, int y) { int k = 0; while (1 << (k + 1) <= y - x + 1) k++; int a = dp[x][k]; int b = dp[y - (1 << k) + 1][k]; if (depth[a] < depth[b]) return a; return b; } int LCA(int x, int y) { x = first[x]; y = first[y]; if (x > y) { x = x ^ y; y = x ^ y; x = x ^ y; } int c = Query(x, y); return ver[c]; } }st; const int N = 10010; bool vis ; int n; void init() { scanf("%d", &n); st.init(n); memset(vis, 0, sizeof(vis)); int u, v; for (int i = 1; i < n; i++) { scanf("%d%d", &u, &v); st.AddEdge(u, v); vis[v] = true; } for (int i = 1; i <= n; i++) if (!vis[i]) { st.solve(i); break; } scanf("%d%d", &u, &v); printf("%d\n", st.LCA(u, v)); } int main() { int test; scanf("%d", &test); while (test--) { init(); } return 0; }
相关文章推荐
- [leetcode] Summary Ranges
- sqlite3基础
- Linux磁盘管理和文件系统管理
- ACM题目
- Android实战简易教程-第五十七枪(分享小米手电筒源码)
- python画柱状图并且输出到html文件
- [备份]部分常用函数
- POJ - 1986 Distance Queries(LCA离线)
- 【日常学习】【其他算法】codevs3371 刮油漆题解
- 实体之间的关系(EF基础系列篇7)
- WeakReference 详解
- php 所有主流框架性能对比(yii、yaf、ci等php框架)
- LCA的离线算法 tarjan
- CSS实现带阴影效果的黑色导航菜单效果
- CMake 学习笔记 —— 进阶
- 面试题18:树的子结构
- 文本文件和二进制文件的区别
- POJ-1504
- Hibernate中,各表映射文件...hbm.xml详解
- 21_03_httpd属性配置