BZOJ1787 [AHOI2008] Meet 紧急集合

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

Description

Input

Output

 

LCA水过

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

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

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

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
",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

BFS Version

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