zoukankan      html  css  js  c++  java
  • bzoj 1787 [Ahoi2008]Meet 紧急集合(1832 [AHOI2008]聚会)

    1787: [Ahoi2008]Meet 紧急集合

    Time Limit: 20 Sec  Memory Limit: 162 MB
    Submit: 1841  Solved: 857
    [Submit][Status][Discuss]

    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 /**************************************************************
     2     Problem: 1787
     3     User: hahalidaxin2
     4     Language: C++
     5     Result: Accepted
     6     Time:3716 ms
     7     Memory:65216 kb
     8 ****************************************************************/
     9  
    10 #include<cstdio>
    11 #include<cstring>
    12 #include<queue>
    13 #include<vector>
    14 #include<iostream>
    15 using namespace std;
    16   
    17 const int maxn = 500000+10;
    18 const int maxd = 19;
    19   
    20 struct Edge{ int u,v;
    21 };
    22 vector<int> G[maxn];
    23 vector<Edge> es;
    24   
    25 int d[maxn];
    26 int p[maxn][maxd];
    27   
    28 void addedge(int u,int v) {
    29     es.push_back((Edge){u,v});
    30     int m=es.size(); G[u].push_back(m-1);
    31 }
    32 void dfs(int u,int fa) { 
    33     for(int i=1;i<=maxd;i++) {       //构造倍增数组 
    34         if(d[u]<(1<<i)) break;
    35         p[u][i]=p[p[u][i-1]][i-1];
    36     }
    37     for(int i=0;i<G[u].size();i++) {
    38         Edge e=es[G[u][i]]; int v=e.v;
    39         if(v!=fa)
    40             d[v]=d[u]+1 , p[v][0]=u , dfs(v,u);
    41     }
    42 }
    43 int lca(int u,int v) {
    44     if(d[v]>d[u]) swap(u,v);
    45     int dep=d[u]-d[v];
    46     for(int i=0;i<maxd;i++)
    47         if((1<<i)&dep) u=p[u][i]; 
    48     if(u==v) return u;
    49     for(int i=maxd-1;i>=0;i--)
    50         if(p[u][i]!=p[v][i])
    51             u=p[u][i] , v=p[v][i];
    52     return p[u][0];
    53 }
    54 int dist(int x,int y) { return d[x]+d[y]-(d[lca(x,y)]<<1); }
    55 int n,m;
    56   
    57 void read(int& x) {
    58     char c=getchar(); 
    59     while(!isdigit(c)) c=getchar();
    60     x=0;
    61     while(isdigit(c))
    62         x=x*10+c-'0' , c=getchar();
    63 }
    64 int main() {
    65     read(n),read(m);
    66     int u,v;
    67     for(int i=0;i<n-1;i++) {
    68         read(u),read(v);
    69         addedge(u,v); addedge(v,u);
    70     }
    71     dfs(n>>1,-1);
    72     int a,b,c,lab,lac,lbc,s;
    73     while(m--) {
    74         read(a),read(b),read(c);
    75         lab=lca(a,b),lac=lca(a,c),lbc=lca(b,c);
    76         if(lab==lac) s=lbc;
    77         else if(lab==lbc) s=lac;
    78         else s=lab;
    79         printf("%d %d
    ",s,dist(a,s)+dist(b,s)+dist(c,s));
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    5月14日 游戏闯关,
    无名管道练习小程序
    关于对进程、线程的返回状态的获取的理解
    C语言中内存分布及程序运行中(BSS段、数据段、代码段、堆栈)
    linux 与会话相关的一些概念、登录过程
    linux进程——fork、vfork 两函数的实现及两者区别
    关于 linux 中init 进程
    linux进程——fork()函数
    linux下 vim多屏幕操作
    linux下进程管理
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5096732.html
Copyright © 2011-2022 走看看