题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1787

Description

BZOJ1787 [AHOI2008] Meet 紧急集合

Input

BZOJ1787 [AHOI2008] Meet 紧急集合

Output

BZOJ1787 [AHOI2008] Meet 紧急集合

 

LCA水过

三个点两两求LCA,若有其中两个LCA一样“集合点”就是第三个LCA

多加inline有用处,DFS改BFS对效率没有什么提高

从上到下依次是DFS(小改),BFS,DFS

BZOJ1787 [AHOI2008] Meet 紧急集合

DFS Version

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #define rep(i,l,r) for(int i=l; i<=r; i++)
 6 #define clr(x,y) memset(x,y,sizeof(x))
 7 #define travel(x) for(Edge *p=last[x]; p; p=p->pre)
 8 using namespace std;
 9 const int INF = 0x3f3f3f3f;
10 const int maxn = 500010;
11 struct Edge{
12     Edge *pre; int to;
13 }edge[maxn<<1];
14 Edge *last[maxn],*pt;
15 int n,m,x,y,z,depth[maxn],fa[maxn][19];
16 bool vis[maxn];
17 inline int read(){
18     int ans = 0, f = 1;
19     char c = getchar();
20     while (!isdigit(c)){
21         if (c == '-') f = -1;
22         c = getchar();
23     }
24     while (isdigit(c)){
25         ans = ans * 10 + c - '0';
26         c = getchar();
27     }
28     return ans * f;
29 }
30 inline void addedge(int x,int y){
31     pt->pre = last[x]; pt->to = y; last[x] = pt++;
32 }
33 void dfs(int x){
34     vis[x] = 1;
35     rep(i,1,18){
36         if (depth[x] < (1 << i)) break;
37         fa[x][i] = fa[fa[x][i-1]][i-1];
38     }
39     travel(x){
40         if (vis[p->to]) continue;
41         depth[p->to] = depth[x] + 1;
42         fa[p->to][0] = x;
43         dfs(p->to);
44     }
45 }
46 inline int lca(int x,int y){
47     if (depth[x] < depth[y]) swap(x,y);
48     int t = depth[x] - depth[y];
49     rep(i,0,18) if (t & (1 << i)) x = fa[x][i];
50     if (x == y) return x;
51     for(int i=18; i>=0; i--) if (fa[x][i] != fa[y][i]){
52         x = fa[x][i]; y = fa[y][i];
53     }
54     return fa[x][0];
55 }
56 inline int calc(int x,int y){
57     return depth[x] + depth[y] - (depth[lca(x,y)] << 1);
58 }
59 inline void solve(int x,int y,int z){
60     int l1 = lca(x,y), l2 = lca(y,z), l3 = lca(x,z), t;
61     if (l1 == l2) t = l3; else if (l2 == l3) t = l1; else t = l2;
62     int ans = calc(x,t) + calc(y,t) + calc(z,t);
63     printf("%d %d\n",t,ans);
64 }
65 int main(){
66     n = read(); m = read(); clr(last,0); pt = edge;
67     rep(i,1,n-1){
68         x = read(); y = read(); addedge(x,y); addedge(y,x);
69     }
70     clr(vis,0); dfs(1);
71     rep(i,1,m){
72         x = read(); y = read(); z = read(); solve(x,y,z);
73     }
74     return 0;
75 }
View Code

相关文章: