• 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
  • 相关阅读:
    java中bean和xml相互转换
    java操作zip文件
    java内置的解压缩工具
    java操作Excel简单入门
    java开发IDEA插件入门
    java中Class.getResourceAsStream()和ClassLoader.getResourceAsStream()的区别
    java中文转拼音
    vue父子组件通信
    学会使用box-sizing布局
    webpack-dev-server 导致的 invalid host header
  • 原文地址:https://www.cnblogs.com/jimzeng/p/bzoj1787.html
Copyright © 2020-2023  润新知