题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4822

Problem Description
Three countries, Red, Yellow, and Blue are in war. The map of battlefield is a tree, which means that there are N nodes and (N – 1) edges that connect all the nodes. Each country has a base station located in one node. All three countries will not place their station in the same node. And each country will start from its base station to occupy other nodes. For each node, country A will occupy it iff other two country's base stations have larger distances to that node compared to country A. Note that each edge is of the same length.

Given three country's base station, you task is to calculate the number of nodes each country occupies (the base station is counted).

 
Input
The input starts with a single integer T (1 ≤ T ≤ 10), the number of test cases.
Each test cases starts with a single integer N (3 ≤ N ≤ 10 ^ 5), which means there are N nodes in the tree.
Then N - 1 lines follow, each containing two integers u and v (1 ≤ u, v ≤ N, u ≠ v), which means that there is an edge between node u and node v.
Then a single integer M (1 ≤ M ≤ 10 ^ 5) follows, indicating the number of queries.
Each the next M lines contains a query of three integers a, b, c (1 ≤ a, b, c ≤ N, a, b, c are distinct), which indicates the base stations of the three countries respectively.
 
Output
For each query, you should output three integers in a single line, separated by white spaces, indicating the number of nodes that each country occupies. Note that the order is the same as the country's base station input.
 
题目大意:给一棵n个点的树,每次询问有三个点,问离每个点比另外两个点近的点有多少个。
思路:贴一下官方题解:
——————————————————————————————————————————————————————————————————————————————

本题抽象的题意是给出一棵树,有许多询问,每次询问,给出3个点,问有多少个点,到这三个点的最短距离是递增的。
首先考虑两个点的简单情况,因为是树,有特殊性,任意两点间只有唯一的一条路,找到路的中点,就可以把树分成两部分,其中一部分的点是合法解。
回到本题,问题就变成了两个子树的交集。这个考虑一个子树是否是另一子树的子树即可。用dfs序列来判断即可。
时间复杂度是O(nlogn)

——————————————————————————————————————————————————————————————————————————————
即考虑每一个点,求这个点与另两个点劈开成的两颗子树(或者是整棵树减去一棵子树),这里要用到树上倍增求第k祖先。然后求两个子树的交,这个分类讨论一下即可。
PS:用G++交居然栈溢出了。只好换C++开栈了。
 
 
代码(2781MS):
 #ifdef ONLINE_JUDGE
#pragma comment(linker, "/STACK:1024000000,1024000000")
#endif // ONLINE_JUDGE #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std; const int MAXV = ;
const int MAXE = ;
const int MAX_LOG = ; int head[MAXV], ecnt;
int to[MAXE], next[MAXE];
int n, m, T; void init() {
memset(head + , -, n * sizeof(int));
ecnt = ;
} void add_edge(int u, int v) {
to[ecnt] = v; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; next[ecnt] = head[v]; head[v] = ecnt++;
} int fa[MAX_LOG][MAXV];
int size[MAXV], dep[MAXV]; void dfs(int u, int f, int depth) {
fa[][u] = f; size[u] = ; dep[u] = depth;
for(int p = head[u]; ~p; p = next[p]) {
int v = to[p];
if(v == f) continue;
dfs(v, u, depth + );
size[u] += size[v];
}
} void initfa() {
dfs(, -, );
for(int k = ; k < MAX_LOG - ; ++k) {
for(int u = ; u <= n; ++u) {
if(fa[k][u] == -) fa[k + ][u] = ;
else fa[k + ][u] = fa[k][fa[k][u]];
}
}
} int upslope(int u, int p) {
for(int k = ; k < MAX_LOG; ++k) {
if((p >> k) & ) u = fa[k][u];
}
return u;
} int lca(int u, int v) {
if(dep[u] < dep[v]) swap(u, v);
u = upslope(u, dep[u] - dep[v]);
if(u == v) return u;
for(int k = MAX_LOG - ; k >= ; --k) {
if(fa[k][u] != fa[k][v])
u = fa[k][u], v = fa[k][v];
}
return fa[][u];
} struct Node {
int type, r;
Node(int type, int r): type(type), r(r) {}
}; Node get_middle(int a, int b, int ab) {
int len = dep[a] + dep[b] - * dep[ab];
if(dep[a] >= dep[b]) {
return Node(, upslope(a, (len - ) / ));
} else {
return Node(, upslope(b, len / ));
}
} int calc(int a, int b, int c, int ab, int ac) {
Node bn = get_middle(a, b, ab), cn = get_middle(a, c, ac);
if(bn.type == && cn.type == ) {
if(dep[bn.r] < dep[cn.r]) swap(bn, cn);
if(lca(bn.r, cn.r) == cn.r) return size[bn.r];
else return ;
} else if(bn.type == && cn.type == ) {
if(dep[bn.r] < dep[cn.r]) swap(bn, cn);
if(lca(bn.r, cn.r) == cn.r) return n - size[cn.r];
else return n - size[bn.r] - size[cn.r];
} else {
if(bn.type == ) swap(bn, cn);
int t = lca(bn.r, cn.r);
if(t == cn.r) return n - size[cn.r];
if(t == bn.r) return size[bn.r] - size[cn.r];
return size[bn.r];
}
} int main() {
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
init();
for(int i = , u, v; i < n; ++i) {
scanf("%d%d", &u, &v);
add_edge(u, v);
}
initfa();
scanf("%d", &m);
for(int i = , a, b, c; i < m; ++i) {
scanf("%d%d%d", &a, &b, &c);
int ab = lca(a, b), ac = lca(a, c), bc = lca(b, c);
printf("%d %d %d\n", calc(a, b, c, ab, ac), calc(b, a, c, ab, bc), calc(c, a, b, ac, bc));
}
}
}

HDU 4822 Tri-war(LCA树上倍增)(2013 Asia Regional Changchun)的更多相关文章

  1. HDU 4816 Bathysphere(数学)(2013 Asia Regional Changchun)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4816 Problem Description The Bathysphere is a spheric ...

  2. 2013 Asia Regional Changchun C

    Little Tiger vs. Deep Monkey Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K ( ...

  3. 2013 Asia Regional Changchun I 题,HDU(4821),Hash

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4821 解题报告:搞了很久,总算搞出来了,还是参考了一下网上的解法,的确很巧,和上次湘潭的比 ...

  4. 2013 Asia Regional Changchun

    Hard Code http://acm.hdu.edu.cn/showproblem.php?pid=4813 #include<cstdio> ]; int main(){ int t ...

  5. HDU 5444 Elven Postman (2015 ACM/ICPC Asia Regional Changchun Online)

    Elven Postman Elves are very peculiar creatures. As we all know, they can live for a very long time ...

  6. 2015 ACM/ICPC Asia Regional Changchun Online HDU 5444 Elven Postman【二叉排序树的建树和遍历查找】

    Elven Postman Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  7. HDU 4291 A Short problem(2012 ACM/ICPC Asia Regional Chengdu Online)

    HDU 4291 A Short problem(2012 ACM/ICPC Asia Regional Chengdu Online) 题目链接http://acm.hdu.edu.cn/showp ...

  8. (并查集)Travel -- hdu -- 5441(2015 ACM/ICPC Asia Regional Changchun Online )

    http://acm.hdu.edu.cn/showproblem.php?pid=5441 Travel Time Limit: 1500/1000 MS (Java/Others)    Memo ...

  9. (二叉树)Elven Postman -- HDU -- 54444(2015 ACM/ICPC Asia Regional Changchun Online)

    http://acm.hdu.edu.cn/showproblem.php?pid=5444 Elven Postman Time Limit: 1500/1000 MS (Java/Others)  ...

随机推荐

  1. 关于Memo或者Edit之类控件, 直接设置Text无法撤销的解决方案

    昨天看到群里有人问使用Memo1.Text := '11111';来设置内容的代码无法使用Memo1.Undo的方式来撤销 测试了一下果然如此, 跟踪了VCL代码, 发现Text := '11111' ...

  2. Qt使用一个事件队列对所有发出的事件进行维护(QObject的event()函数相当于dispatch函数),用EventLabel 继承QLabel作为例子(简单明了) good

    事件(event)是由系统或者 Qt 本身在不同的时刻发出的.当用户按下鼠标.敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事件.一些事件在对用户操作做出响应时发出,如键盘事件等:另一些事 ...

  3. 使用ASP.NET web API创建REST服务(二)

    Creating a REST service using ASP.NET Web API A service that is created based upon the architecture ...

  4. Spring框架,如何返回数据给视图(jsp文件)

    第一步 准备返回给视图的数据 package com.cwebs.samples; import java.util.LinkedHashMap; import java.util.List; imp ...

  5. [LeetCode]题解(python):033-Search in Rotated Sorted Array

    题目来源 https://leetcode.com/problems/search-in-rotated-sorted-array/ Suppose a sorted array is rotated ...

  6. 错误提示: An App ID with identifier "*****" is not avaliable. Please enter a different string.

    百度了很多,但大多的解决办法就是 更改BundleID,的确管用,,但是有的情况下,你需要跟同事合作,公用同一个BundleID, 我是这样处理的:工具栏中打开Window—project删除所有工程 ...

  7. EChars学习-1

    Echarts,编写来自Enterprise Charts,商业级数据图表,是百度的一个开源的数据可视化工具 官网地址:http://echarts.baidu.com/ 一.引入Echarts &l ...

  8. Swift vs. Objective-C:未来看好 Swift 的十个理由

    Swift vs. Objective-C:未来看好 Swift 的十个理由 是时候使用易入手又全面的Swif语言为iOS和mac OS X做应用开发了. 虽然编程语言不会那么容易消逝,但坚持衰落范例 ...

  9. H3C Series Router MSR26-00与F3736 VPN IP SEC

    注:建立链接之后经常断线,需要两边进行PING通才可以.待解决.

  10. Java Volatile关键字

    在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写. 这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量 ...