zoukankan      html  css  js  c++  java
  • [BZOJ 1787 & 1832] [Ahoi2008] Meet 紧急集合

    1787 & 1832: [Ahoi2008]Meet 紧急集合

    Time Limit: 10 Sec / 20 Sec
    Memory Limit: 162 MB

    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

    【题解】
    可以证明,最小的点一定在三点中任意两点的LCA上,那么只要用倍增来求下LCA即可。
    注意,本题树根节点在1,因为你不知道父亲孩子的关系所以需要建两条边,BFS加一个判断就好
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int to[1000010],next[1000010],dep[1000010];
     4 int p[500010][21],n,m,head[500010],root,tot=0;
     5 bool deg[500010];
     6 inline void bfs(int root) {
     7     queue<int> Q;
     8     p[root][0]=root; dep[root]=0;
     9     Q.push(root);
    10     while(!Q.empty()) {
    11         int u=Q.front();Q.pop();
    12         for (int i=1;i<=20;++i) p[u][i]=p[p[u][i-1]][i-1];
    13         for (int i=head[u];i!=-1;i=next[i])
    14             if(to[i]!=p[u][0]) {
    15                 int v=to[i];
    16                 dep[v]=dep[u]+1; p[v][0]=u;
    17                 Q.push(v);
    18             }
    19     }
    20 }
    21 inline int lca(int x,int y) {
    22     if(dep[x]<dep[y]) {int t=x;x=y;y=t;}
    23     for (int i=20;i>=0;--i) if((dep[x]-dep[y]) & (1<<i)) x=p[x][i];
    24     if(x==y) return x;
    25     for (int i=20;i>=0;--i) 
    26         if(p[x][i]!=p[y][i])  
    27             x=p[x][i],y=p[y][i];  
    28     return p[x][0];  
    29 }
    30 inline int getdist(int u,int v) {
    31     return dep[u]+dep[v]-(dep[lca(u,v)]<<1);
    32 }
    33 int main() {
    34     memset(head,-1,sizeof(head));
    35     memset(deg,0,sizeof(deg));
    36     scanf("%d%d",&n,&m);
    37     for (int i=1;i<=n-1;++i) {
    38         int u,v;
    39         scanf("%d%d",&u,&v);
    40         to[tot]=v;
    41         next[tot]=head[u];
    42         head[u]=tot++;
    43         int t=u;u=v;v=t;
    44         to[tot]=v;
    45         next[tot]=head[u];
    46         head[u]=tot++;
    47     }
    48     bfs(1);
    49     int a1,a2,a3,b1,b2,b3,u,v,w;
    50     while(m--) {
    51         scanf("%d%d%d",&u,&v,&w);
    52         a1=lca(u,v); b1=dep[u]+dep[v]-(dep[a1]<<1)+getdist(a1,w);
    53         a2=lca(u,w); b2=dep[u]+dep[w]-(dep[a2]<<1)+getdist(a2,v);
    54         a3=lca(v,w); b3=dep[v]+dep[w]-(dep[a3]<<1)+getdist(a3,u);
    55         //printf("   %d %d
    ",a1,b1);printf("   %d %d
    ",a2,b2);printf("   %d %d
    ",a3,b3);
    56         if(b1<b2) {
    57             if(b1<b3) printf("%d %d
    ",a1,b1);
    58             else printf("%d %d
    ",a3,b3);
    59         } else {
    60             if (b2<b3)printf("%d %d
    ",a2,b2);
    61             else printf("%d %d
    ",a3,b3);
    62         }
    63     }
    64 }
    View Code

    计算距离的时候只需要dep[x]+dep[y]-dep[lca(x,y)]*2就好了。

    BZOJ 26题了好开心WWW

  • 相关阅读:
    关于iterator的一点疑惑
    shuffle()方法
    List简单使用笔记
    Arrays.asList()
    多项式ADT(数组存储多项式系数和指数)笔记
    《数据结构与算法分析C语言描述》源码网盘分享
    C语言实现链表
    typedef的用法
    #ifndef的用法
    mysql创建数据库和数据表模板
  • 原文地址:https://www.cnblogs.com/TonyNeal/p/bzoj1787.html
Copyright © 2011-2022 走看看