ZOJ 3195(LCA模板)
2016-05-01 16:25
337 查看
题意:给一个带权图 然后q个询问 每个询问有三个数x y z,求x y z这三个点连接起来需要多少距离。
LCA 对于每个询问求出任意两个点对的LCA 加和 / 2。
LCA 对于每个询问求出任意两个点对的LCA 加和 / 2。
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <queue> using namespace std; const int dx[] = {-1, 0, 1, 0}; const int dy[] = {0, 1, 0, -1}; const int maxn = 50000 + 7; const int INF = ~0U >> 1; struct node { int v, val; }; struct ask { int u, v, lca; }; vector<node> G[maxn]; vector<ask> e; vector<int> query[maxn]; int p[maxn], ans[maxn], d[maxn], vis[maxn]; int n, q; int Find(int x) { return p[x] == x ? x : p[x] = Find(p[x]); } void addEdge(int u, int v, int val) { G[u].push_back((node) {v, val}); G[v].push_back((node) {u, val}); } void addAsk(int u, int v) { e.push_back((ask) {u, v, -1}); e.push_back((ask) {v, u, -1}); int len = e.size() - 1; query[u].push_back(len - 1); query[v].push_back(len); } void init() { for(int i = 0; i < n; ++i) p[i] = i, G[i].clear(), query[i].clear(); memset(d, 0, sizeof(d)); memset(vis, 0, sizeof(vis)); memset(ans, 0, sizeof(ans)); e.clear(); } void Tarjan(int u, int val) { vis[u] = 1; ans[u] = u; d[u] = val; for(int i = 0; i < G[u].size(); ++i) { node& to = G[u][i]; if(!vis[to.v]) { Tarjan(to.v, val + to.val); int x = Find(u), y = Find(to.v); if(x != y) p[to.v] = u; } } for(int i = 0; i < query[u].size(); ++i) { int w = query[u][i]; ask& temp = e[w]; if(vis[temp.v]) temp.lca = e[w^1].lca = ans[Find(temp.v)]; } } int main() { int u, v, val; int kase = 0; while(scanf("%d", &n) != EOF) { init(); for(int i = 0; i < n - 1; ++i) { scanf("%d%d%d", &u, &v, &val); addEdge(u, v, val); } scanf("%d", &q); int x, y, z; for(int i = 0; i < q; ++i) { scanf("%d%d%d", &x, &y, &z); addAsk(x, y); addAsk(x, z); addAsk(y, z); } if(kase) puts(""); kase++; Tarjan(0, 0); int ans = 0; for(int i = 0; i < 3 * q; ++i) { ans += (d[e[i*2].u] + d[e[i*2].v] - 2 * d[e[i*2].lca]); if(i % 3 == 2) { printf("%d\n", ans / 2); ans = 0; } } } return 0; }
相关文章推荐
- tomcat和apache连接器mod_jk (Tomcat Connectors)
- Maple OpenMaple (API) 开发系列-1.0 概述
- 树T1交换其(某些)左右节点的左右儿子变换成树T2,则是同构。给出一个多项式时间算法以决定是否两棵树同构
- 《Java程序设计》第9周学习总结
- 《深入.NET平台和C# 编程》内部测试 笔试题
- [git]修改commit
- POJ 3159 Candies (差分约束)
- 【CI学习笔记】引入jquery,以及文件夹结构的改变
- HDOJ-5677 ztr loves substring
- 异常 dubbo demo中 consumer消费的问题
- apache+jkmount+tomcat
- 剑指offer(64):序列化二叉树
- HTTP请求
- 安卓java.lang.IllegalArgumentException: The observer is null.解决方案
- 杨辉三角形
- 安卓java.lang.IllegalArgumentException: The observer is null.解决方案
- NSDictionary转NSData【相互转换】
- CentOs 7.0安装JDK、MySQL和Tomcat
- 基本登录页面的实现
- tomcat和apache连接器mod_jk (tomcat connectors)