• bzoj2237[NCPC2009]Flight Planning 结论题?


    2237: [NCPC2009]Flight Planning

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 55  Solved: 27
    [Submit][Status][Discuss]

    Description

    S航空公司在N座城市之间有N-1条航线,航线是双向的。任意两座城市都是可以互相到达的,但是可能需要在一些城市换乘不同的航线。

    目前有人抱怨要到达有些城市需要换乘太多次,S航空公司为了缓解这一现状,决定取消目前的一条航线,添加另一条航线,在保证任意两座城市还是可以互相到达的前提下,使得两座城市之间需要乘坐的航线次数的最大值最小。

    Input

    第一行为一个整数N(4<=N<=2500),表示城市的个数。城市从1到N编号。

    接下来N-1行,每行是一对整数a和b,表示一条连接a和b的航线(1<=a,b<=N)。

    Output

    输出仅一行,即航空公司进行调整后,任意两座城市之间需要乘坐的航班次数的最大值。

    Sample Input


    4

    1 2

    2 3

    3 4

    Sample Output


    2

    【样例解释】

    取消3-4的航线,添加2-4的航线。

    HINT

    对于100%的数据,N<=2500。

    题意:在一棵树上,你可以任意删除一条边再加上一条并使得这个图还是颗树,在此前提下,你要让树的直径最小,求最小直径

    n^2是可以接受的
    枚举每一条边,把它断开,形成两个联通块,对这两个联通块求直径l1 l2
    那么ans=min(ans,max(l1,l2,(l1+1)/2+(l2+1)/2+1))
    简单说明一下后面那一坨:
    对于两棵树,要把它们连起来后是直径最小,肯定是链接两颗树直径的中点
    用反证法可以证明这样更优:假设选择另外的点链接,那么直径两端(a , b)到它的距离的max(disa,disb) 不会比到中点的距离短

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define N 2505
     6 using namespace std;
     7 int n,tot=1,l1,l2,hd[N],dis[N],x[N],y[N],ban[N<<1];
     8 struct edge{int u,v,next;}e[N<<1];
     9 void adde(int u,int v){
    10     e[++tot].v=v;
    11     e[tot].u=u;
    12     e[tot].next=hd[u];
    13     hd[u]=tot; 
    14 }
    15 void dfs(int u,int fa){
    16     for(int i=hd[u];i;i=e[i].next){
    17         int v=e[i].v;
    18         if(v==fa||ban[i])continue;
    19         dis[v]=dis[u]+1;
    20         dfs(v,u); 
    21     }
    22 }
    23 int getlen(int x){
    24     int t1,t2;
    25     memset(dis,0,sizeof(dis));
    26     dfs(x,0);t1=x;
    27     for(int i=1;i<=n;i++)
    28     if(dis[i]>dis[t1])t1=i;
    29     memset(dis,0,sizeof(dis));
    30     dfs(t1,0);t2=t1;
    31     for(int i=1;i<=n;i++)
    32     if(dis[i]>dis[t2])t2=i;
    33     return dis[t2];
    34 }
    35 int main(){
    36     scanf("%d",&n);
    37     for(int i=1;i<n;i++){
    38         int u,v;
    39         scanf("%d%d",&u,&v);
    40         adde(u,v);adde(v,u); 
    41     }int ans=1<<30;
    42     for(int i=2;i<=tot;i+=2){
    43         ban[i]=ban[i^1]=1;
    44         l1=getlen(e[i].u);
    45         l2=getlen(e[i].v);
    46         ans=min(ans,max(l1,max(l2,(l1+1)/2+(l2+1)/2+1)));
    47         ban[i]=ban[i^1]=0;
    48     }printf("%d",ans);
    49     return 0;
    50 }
  • 相关阅读:
    802.11帧
    art中的部分内容,留着慢慢研究
    802.11基础知识
    opkg
    openwrt生成备份文件
    lua中获取时间
    php学习四:数组(一)
    php学习三:函数
    php学习二:表达式
    php学习一:语法规则
  • 原文地址:https://www.cnblogs.com/wsy01/p/8111084.html
Copyright © 2020-2023  润新知