Evanyou Blog 彩带

洛谷P4281 紧急会议

传送门啦

思路:

$ Lca $ 这个题要求这个显而易见吧。但是难就难在怎么在树上利用 $ Lca $ 去解决三个点的问题。

首先明确三个点两两的 三个 $ Lca $ 中有一对是相等的,我们也会发现这个相同的 $ Lca $ 肯定是深度最小的一个 $ Lca $ 。可以动手画一下图试试。

同样也用了一下树上差分的知识。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#define re register
using namespace std ;
const int maxn = 500005 ;

inline int read () {
	int f = 1 , x = 0 ; 
	char ch = getchar () ;
	while(ch > '9' || ch < '0') {if(ch == '-') f = -1 ; ch = getchar () ;}
	while(ch >= '0' && ch <= '9')  {x = (x << 1) + (x << 3) + ch - '0' ; ch = getchar () ;}
	return x * f ;
}

int n , m , u , v , a , b , c ;
int head[maxn] , tot ;

struct Edge {
	int from , to , next ;
}edge[maxn << 1] ;

inline void add (int u , int v) {
	edge[++tot].from = u ;
	edge[tot].to = v ; 
	edge[tot].next = head[u] ;
	head[u] = tot ;
}

int dep[maxn] , f[maxn][21] ;

inline void dfs(int x , int fa) {
	dep[x] = dep[fa] + 1 ;
	f[x][0] = fa ;
	for(re int i = 1 ; (1 << i) <= dep[x] ; ++ i) {
		f[x][i] = f[f[x][i - 1]][i - 1] ;
	}
	for(re int i = head[x] ; i ; i = edge[i].next) {
		int v = edge[i].to ;
		if(v != fa)  dfs(v , x) ;
	}
}

inline int lca(int a , int b) {
	if(dep[a] < dep[b])  swap(a , b) ;
	for(re int i = 20 ; i >= 0 ; -- i) {
		if((1 << i) <= (dep[a] - dep[b])) {
			a = f[a][i] ;
		}
	}
	if(a == b)  return a ;
	for(re int i = 20 ; i >= 0 ; -- i) {
		if((1 << i) <= dep[a] && (f[a][i] != f[b][i])) {
			a = f[a][i] ;
			b = f[b][i] ;
		}
	}
	return f[a][0] ;
}
 
int main () {
	n = read () ; m = read () ;
	for(re int i = 1 ; i <= n - 1 ; ++ i) {
		u = read () ; v = read () ;
		add(u , v) ;
		add(v , u) ;
	}
	dfs(1 , 0) ;
	for(re int i = 1 ; i <= m ; ++ i) {
		a = read () ; b = read () ; c = read () ;
		int root = 0 , ans = 0 ; 
		int r1 = lca(a , b) ;
		int r2 = lca(b , c) ;
		int r3 = lca(a , c) ;
		if(r1 == r2)  root = r3 ;
		else if(r1 == r3)  root = r2 ;
		else root = r1 ;
		ans = dep[a] + dep[b] + dep[c] - dep[r1] - dep[r2] - dep[r3] ;
		printf("%d %d\n" , root , ans) ;
	}
	return 0 ;
}	
posted @ 2019-02-28 21:37  Stephen_F  阅读(164)  评论(0编辑  收藏  举报