zoukankan      html  css  js  c++  java
  • bzoj 1787 Meet 紧急集合

    Meet 紧急集合

    这个题是在脖子oj(清北某奆佬给起的名字)八中oj(大视野在线评测)上的。

    给出bzoj链接

    这个题还是求最近公共祖先的问题。

    而该题不同于别的题,它是需要求三个点的最近公共祖先。

    我们就需要求出三个点两两之间的LCA。

    而这三个LCA之间,必有两个是相同的。

    如果两个点相同,那另一点就是那三个点的LCA。

    如果三个点都相同,那么该点就是那三个点的LCA。

    最后还需要统计走过的边的长度。

    三个点都相同的情况很好搞,就是计算三个点与那个LCA的深度差,加起来就是答案。

    但是两个点就难一点。如果lca_a_b与lca_a_c相同,就需要求出lca_b_c到a,b,c的长度,就可以转化成b,c到它们的最近公共祖先lca_b_c的长度,和lca_b_c,a到它们的最近公共祖先lca_a_b(或lca_a_c)的长度。

    那么就先求出lca_b_c与b和c的深度差,再求出lca_a_b(或lca_a_c)与lca_b_c和a的深度差,加起来就是结果。

    代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #define N 500010
     5 #define M 1000010
     6 using namespace std;
     7 int next[M],to[M],head[N],num,size[N],deep[N],father[N],top[N],n,m,a,b,c,c1,c2,c3,ans;
     8 void add(int false_from,int false_to){
     9     next[++num]=head[false_from];
    10     to[num]=false_to;
    11     head[false_from]=num;
    12 }
    13 void dfs1(int x){
    14     size[x]=1;
    15     deep[x]=deep[father[x]]+1;
    16     for(int i=head[x];i;i=next[i])
    17         if(father[x]!=to[i]){
    18             father[to[i]]=x;
    19             dfs1(to[i]);
    20             size[x]+=size[to[i]];
    21         }
    22 }
    23 void dfs2(int x){
    24     int mmax=0;
    25     if(!top[x])
    26         top[x]=x;
    27     for(int i=head[x];i;i=next[i])
    28         if(father[x]!=to[i]&&size[to[i]]>size[mmax])
    29             mmax=to[i];
    30     if(mmax){
    31         top[mmax]=top[x];
    32         dfs2(mmax);
    33     }
    34     for(int i=head[x];i;i=next[i])
    35         if(father[x]!=to[i]&&to[i]!=mmax)
    36             dfs2(to[i]);
    37 }
    38 int lca(int x,int y){
    39     while(top[x]!=top[y]){
    40         if(deep[top[x]]<deep[top[y]])
    41             swap(x,y);
    42         x=father[top[x]];
    43     }
    44     if(deep[x]<deep[y])return x;
    45     return y;
    46 }
    47 int main(){
    48     scanf("%d%d",&n,&m);
    49     for(int i=1;i<n;++i){
    50         scanf("%d%d",&a,&b);
    51         add(a,b);
    52         add(b,a);
    53     }
    54     dfs1(1);
    55     dfs2(1);
    56     for(int i=1;i<=m;++i){
    57         scanf("%d%d%d",&a,&b,&c);
    58         ans=0;
    59         c1=lca(a,b);
    60         c2=lca(a,c);
    61         c3=lca(b,c);
    62         if(c1==c2&&c2==c3){
    63             ans=abs(deep[c1]-deep[a])+abs(deep[c1]-deep[b])+abs(deep[c1]-deep[c]);
    64             printf("%d %d
    ",c1,ans);
    65         }
    66         else
    67             if(c1==c2){
    68                 ans+=deep[b]+deep[c]-deep[c3]*2;
    69                 ans+=deep[c3]+deep[a]-deep[c1]*2;
    70                 printf("%d %d
    ",c3,ans);
    71             }    
    72         else
    73             if(c1==c3){
    74                 ans+=deep[a]+deep[c]-deep[c2]*2;
    75                 ans+=deep[c2]+deep[b]-deep[c1]*2;
    76                 printf("%d %d
    ",c2,ans);
    77             }    
    78         else{
    79             ans+=deep[a]+deep[b]-deep[c1]*2;
    80             ans+=deep[c1]+deep[c]-deep[c2]*2;
    81             printf("%d %d
    ",c1,ans);
    82         }    
    83     }
    84     return 0;
    85 }
    View Code
  • 相关阅读:
    beaglebone black教程1-ssh登录和新建一个账户
    入职南大富士通一周感想
    stm32的内存分配以及text、bss、data段的意思
    初识modbus
    使用github上面别人的pyqt4+pyserial代码的时遇到的问题
    在MDK V5.12.0环境下建立2440的裸机开发环境
    Eclipse 插件
    Using Notepad++ To Quickly Format XML
    批处理检测外部命令是否存在的模块
    springside4
  • 原文地址:https://www.cnblogs.com/jsawz/p/6815886.html
Copyright © 2011-2022 走看看