• ZOJ-3820 Building Fire Stations 题解


    题目大意:

      一棵树,在其中找两个点,使得其他点到这两个的距离的较小值的最大值的最小值及其方案。

    思路:

      首先显然一棵树的直径的中点到其他点的距离的最大值必定比其他点的小。

      那么感性思考一下就将一棵树的直径平分成两段,在找分成的两棵树的直径的中点。

      PS:dfs貌似要爆栈,用非递归或bfs。

    代码:

     1 #include<cstdio>
     2 const int M=200005;
     3 int ed,cnt,fa[M],q[M],dep[M],v[M<<1],nex[M<<1],hea[M];
     4 bool vis[M];
     5 
     6 int read()
     7 {
     8     int x=0; char ch=getchar();
     9     while (ch<'0' || ch>'9') ch=getchar();
    10     while (ch>='0' && ch<='9') x=(x<<1)+(x<<3)+ch-48,ch=getchar();
    11     return x;
    12 }
    13 
    14 void add(int x,int y) { v[++cnt]=y,nex[cnt]=hea[x],hea[x]=cnt; }
    15 
    16 void build(int s)
    17 {
    18     int h=0,t=1; fa[s]=0;
    19     dep[q[1]=ed=s]=1;
    20     while (h^t)
    21     {
    22         int x=q[++h],y,i;
    23         for (i=hea[x];i;i=nex[i])
    24             if (!vis[y=v[i]] && y^fa[x])
    25             {
    26                 dep[y]=dep[fa[q[++t]=y]=x]+1;
    27                 if (dep[ed]<dep[y]) ed=y;
    28             }
    29     }
    30 }
    31 
    32 void getdis(int x) { build(x); build(ed); }
    33 
    34 int main()
    35 {
    36     for (int T=read();T;--T)
    37     {
    38         int n=read(),ans,i,len,x,y,z;
    39         for (cnt=i=0;i<=n;++i) hea[i]=0;
    40         for (i=1;i<n;++i)
    41         {
    42             x=read(),y=read();
    43             add(x,y),add(y,x);
    44         }
    45         getdis(1); len=dep[x=ed];
    46         for (;dep[x]!=(len>>1)+1;x=fa[x]);
    47         vis[x]=1; getdis(fa[x]); len=dep[y=ed];
    48         for (;dep[y]!=(len>>1)+1;y=fa[y]);
    49         ans=len>>1; vis[x]=0; vis[z=fa[x]]=1;
    50         getdis(x); len=dep[ed]; vis[z]=0;
    51         for (;dep[ed]!=(len>>1)+1;ed=fa[ed]);
    52         len=len>>1; if (ans<len) ans=len;
    53         printf("%d %d %d
    ",ans,y,ed);
    54     }
    55     return 0;
    56 }
  • 相关阅读:
    BOM
    定位
    浮动
    行内元素和块级元素
    Java SE之正则表达式五:切割
    Java SE之正则表达式四:获取
    Java SE之正则表达式三:替换
    Java SE之正则表达式二:匹配
    Java SE之正则表达式一:概述
    [C++]PAT乙级1012.数字分类 (20/20)
  • 原文地址:https://www.cnblogs.com/HHshy/p/6160311.html
Copyright © 2020-2023  润新知