这道题用 LCA 就可以水过去 , 但是我太弱了 QAQ 倍增写LCA总是写残...于是就写了树链剖分...

其实也不难写 , 线段树也不用用到 , 自己YY一下然后搞一搞就过了...速度还挺快的好像= = #9

----------------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
 
#define rep( i , n ) for( int i = 0 ; i < n ; i++ )
#define clr( x , c ) memset( x , c , sizeof( x ) )
#define REP( x ) for( edge* e = head[ x ] ; e ; e = e -> next )
 
using namespace std;
 
const int maxn = 500000 + 5;
 
struct edge {
int to;
edge* next;
};
 
edge* pt , EDGE[ maxn << 1 ];
edge* head[ maxn ];
 
void edge_init() {
pt = EDGE;
clr( head , 0 );
}
 
void add( int u , int v ) {
pt -> to = v;
pt -> next = head[ u ];
head[ u ] = pt++;
}
#define add_edge( u , v ) add( u , v ) , add( v , u )
 
 
int fa[ maxn ] , top[ maxn ] , size[ maxn ] , son[ maxn ] , dep[ maxn ];
int id[ maxn ] , _id[ maxn ] , id_cnt = 0 , TOP;
 
void dfs( int x ) {
size[ x ] = 1;
son[ x ] = -1;
REP( x ) {
int to = e -> to;
if( to == fa[ x ] ) continue;
dep[ to ] = dep[ x ] + 1;
fa[ to ] = x;
dfs( to );
size[ x ] += size[ to ];
if( son[ x ] == - 1 || size[ to ] > size[ son[ x ] ] )
   son[ x ] = to;
}
}
 
void DFS( int x ) {
top[ x ] = TOP;
id[ x ] = ++id_cnt;
_id[ id_cnt ] = x;
if( son[ x ] != -1 )
   DFS( son[ x ] );
REP( x ) if( id[ e -> to ] < 0 )
   DFS( TOP = e -> to );
}
 
void DFS_init() {
clr( id , -1 );
dfs( dep[ 0 ] = 0 );
DFS( TOP = 0 );
}
 
int Q_LCA( int x , int y ) {
while( top[ x ] != top[ y ] ) {
if( dep[ top[ x ] ] < dep[ top[ y ] ] ) 
   swap( x , y );
x = fa[ top[ x ] ];
}
return dep[ x ] < dep[ y ] ? x : y;
}
 
int Q_dist( int x , int y ) {
int res = 0;
while( top[ x ] != top[ y ] ) {
if( dep[ top[ x ] ] < dep[ top[ y ] ] )
   swap( x , y );
res += id[ x ] - id[ top[ x ] ];
x = fa[ top[ x ] ];
res++;
}
if( dep[ x ] < dep[ y ] )
   swap( x , y );
return res + id[ x ] - id[ y ];
}
 
 
int ans[ 2 ];
void work( int x , int y , int z ) {
int LCA[ 3 ] = { Q_LCA( x , y ) , Q_LCA( x , z ) , Q_LCA( y , z ) };
if( LCA[ 0 ] == LCA[ 1 ] )
   ans[ 0 ] = LCA[ 2 ];
else if( LCA[ 0 ] == LCA[ 2 ] )
   ans[ 0 ] = LCA[ 1 ];
else 
   ans[ 0 ] = LCA[ 0 ];
ans[ 1 ] = Q_dist( x , ans[ 0 ] ) + Q_dist( y , ans[ 0 ] ) + Q_dist( z , ans[ 0 ] );
}
 
inline int read() {
int res = 0;
char c = getchar();
while( ! isdigit( c ) ) c = getchar();
while( isdigit( c ) ) {
res = res * 10 + c - '0';
c = getchar();
}
return res;
}
 
int main() {
freopen( "test.in" , "r" , stdin );
int n = read() , m = read();
edge_init();
rep( i , n - 1 ) {
int u = read() , v = read();
u-- , v--;
add_edge( u , v );
}
DFS_init();
while( m-- ) {
int x = read() , y = read() , z = read();
x-- , y-- , z--;
work( x , y , z );
printf( "%d %d\n" , ans[ 0 ] + 1 , ans[ 1 ] );
}
return 0;
}

----------------------------------------------------------------------------------

1787: [Ahoi2008]Meet 紧急集合

Time Limit: 20 Sec  Memory Limit: 162 MB
Submit: 1542  Solved: 683
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

6 4
1 2
2 3
2 4
4 5
5 6
4 5 6
6 3 1
2 4 4
6 6 6

Sample Output

5 2
2 5
4 1
6 0

HINT

Source

BZOJ 1787: [Ahoi2008]Meet 紧急集合( 树链剖分 )的更多相关文章

  1. bzoj 1787: [Ahoi2008]Meet 紧急集合

    1787: [Ahoi2008]Meet 紧急集合 Description Input Output Sample Input 6 4 1 2 2 3 2 4 4 5 5 6 4 5 6 6 3 1 ...

  2. bzoj 1787 [Ahoi2008]Meet 紧急集合(1832 [AHOI2008]聚会)

    1787: [Ahoi2008]Meet 紧急集合 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1841  Solved: 857[Submit][ ...

  3. BZOJ 1787: [Ahoi2008]Meet 紧急集合 LCA

    1787: [Ahoi2008]Meet 紧急集合 Description Input Output Sample Input 6 4 1 2 2 3 2 4 4 5 5 6 4 5 6 6 3 1 ...

  4. BZOJ 1787: [Ahoi2008]Meet 紧急集合(lca+贪心)

    [Ahoi2008]Meet 紧急集合 Description Input Output Sample Input 6 4 1 2 2 3 2 4 4 5 5 6 4 5 6 6 3 1 2 4 4 ...

  5. bzoj 1787: [Ahoi2008]Meet 紧急集合【树链剖分lca】

    对于三个点求最小路径长度和,答案肯定在某两个点的lca上,因为如果把集合点定在公共lca上,一定有两个点汇合后再一起上到lca,这样显然不如让剩下的那个点下来 这个lca可能是深度最深的--但是我懒得 ...

  6. BZOJ——1787: [Ahoi2008]Meet 紧急集合

    http://www.lydsy.com/JudgeOnline/problem.php?id=1787 题目描述 输入 输出 样例输入 6 4 1 2 2 3 2 4 4 5 5 6 4 5 6 6 ...

  7. 1787: [Ahoi2008]Meet 紧急集合

    1787: [Ahoi2008]Meet 紧急集合 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1482  Solved: 652[Submit][ ...

  8. BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)

    前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...

  9. [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3531 分析: 对于每个颜色(颜色<=10^5)都建立一颗线段树 什么!那么不是M ...

随机推荐

  1. Spring学习之注入方式

    我们知道,Spring对象属性的注入方式有两种:设值注入和构造注入. 假设有个类为People,该对象包含三个属性,name和school还有age,这些属性都有各自的setter和getter方法, ...

  2. 弹出窗口内嵌iframe 框口自适应

    说一下,弹出窗口还有内嵌一个iframe 这种模式应该是不科学的,但是公司项目里面就偏偏用到了,它这高低还不能只适应,所以我痛苦的日子来了 分析一下: 首先window.showDialog 方法的时 ...

  3. Android 调用webservice faultactor 错误

    1.错误:02-05 09:56:17.266: E/WebServiceUtil(801): --- 内部异常堆栈跟踪的结尾 ---' faultactor: 'null' detail: org. ...

  4. bzoj 1295: [SCOI2009]最长距离

    题目链接 1295: [SCOI2009]最长距离 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1165  Solved: 619[Submit][ ...

  5. windows文件快速搜索软件推荐

    everything文件搜索工具,可以快速搜索windows下的文件

  6. Java使用freemarker导出word和excel

    www.linxiaosheng.com/post/2013-12-05/40060346181 https://github.com/upyun/java-sdk

  7. 一劳永逸让windows 64位操作系统 禁止强制驱动签名

    如何让WINDOWS7 64位直接加载“禁用强制驱动程序签名”方式启动  Windows Client 论坛 > Windows 7 问题 0 登录进行投票 因为开发需要,要装一台设备的驱动,但 ...

  8. hdu4336 Card Collector 状态压缩dp

    Card Collector Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...

  9. linux: telnet

    问题: telnet: connect to address 192.168.1.103: Connection refused 总结:{ 1. 需要开启telnet服务, /etc/xinetd.d ...

  10. STL之list(双向链表)

    一,概述 List将元素按顺序储存在链表中. 与向量(vectors)相比, 它允许快速的插入和删除,但是随机访问却比较慢. list 不仅是一个双向链表,而且是一个环状双向链表 二,使用 #incl ...