zoukankan      html  css  js  c++  java
  • codevs 3279 奶牛健美操

    3279 奶牛健美操

     

    USACO

     时间限制: 2 s
     空间限制: 256000 KB
     题目等级 : 钻石 Diamond
     
     
     
    题目描述 Description

    Farmer John为了保持奶牛们的健康,让可怜的奶牛们不停在牧场之间
    的小路上奔跑。这些奶牛的路径集合可以被表示成一个点集和一些连接
    两个顶点的双向路,使得每对点之间恰好有一条简单路径。简单的说来,
    这些点的布局就是一棵树,且每条边等长,都为1。

    对于给定的一个奶牛路径集合,精明的奶牛们会计算出任意点对路径的最大值,
    我们称之为这个路径集合的直径。如果直径太大,奶牛们就会拒绝锻炼。

    Farmer John把每个点标记为1..V (2 <= V <= 100,000)。为了获得更加短
    的直径,他可以选择封锁一些已经存在的道路,这样就可以得到更多的路径集合,
    从而减小一些路径集合的直径。

    我们从一棵树开始,FJ可以选择封锁S (1 <= S <= V-1)条双向路,从而获得
    S+1个路径集合。你要做的是计算出最佳的封锁方案,使得他得到的所有路径集合
    直径的最大值尽可能小。

    Farmer John告诉你所有V-1条双向道路,每条表述为:顶点A_i (1 <= A_i <= V) 
    和 B_i (1 <= B_i <= V; A_i!= B_i)连接。

    我们来看看如下的例子:

    线性的路径集合(7个顶点的树)

                       

    1---2---3---4---5---6---7

    如果FJ可以封锁两条道路,他可能的选择如下:

              

    1---2 | 3---4 | 5---6---7

     

    这样最长的直径是2,即是最优答案(当然不是唯一的)。

     

    输入描述 Input Description

    * 第1行: 两个空格分隔的整数V和S

    * 第2...V行: 两个空格分隔的整数A_i和B_i

    输出描述 Output Description

    * 第1行:一个整数,表示FJ可以获得的最大的直径。

    样例输入 Sample Input

    7 2

    6 7

    3 4

    6 5

    1 2

    3 2

    4 5

    样例输出 Sample Output

    2

    数据范围及提示 Data Size & Hint

    对于50%的数据,满足V<=100;

    对于100%的数据,满足V<=100000

    /*
    二分答案+树形dp 
    codevs 一个点RE 估计是爆栈 
    bzoj 过了 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define maxn 100010
    using namespace std;
    int n,s,topt,l,r,ans,sum;
    int first[maxn];
    priority_queue<int>q[maxn];
    struct edge
    {
        int to;
        int next;
    }e[maxn*2];
    int init()
    {
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    void add(int x,int y)
    {
        topt++;
        e[topt].to=y;
        e[topt].next=first[x];
        first[x]=topt;
    }
    int dfs(int x,int from,int limit)
    {
        while(!q[x].empty())q[x].pop();
        q[x].push(0);q[x].push(0);
        for(int i=first[x];i;i=e[i].next)
        {
            int to=e[i].to;
            if(to==from)continue;
            int ha=dfs(to,x,limit);
            q[x].push(ha+1);
        }
        while(1)
        {
            int ha=q[x].top();q[x].pop();
            int he=q[x].top();
            if(ha+he>limit)
                sum++;
            else
            {
                q[x].push(ha);
                break;
            }
        }
        return q[x].top();
    }
    int judge(int x)
    {
        sum=0;dfs(1,0,x);
        return sum<=s;
    }
    int main()
    {
        n=init();s=init();
        for(int i=1;i<=n-1;i++)
        {
            int x,y;
            x=init();y=init();
            add(x,y);add(y,x);
        }
        l=0,r=n;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(judge(mid))
            {
                r=mid-1;
                ans=mid;
            }
            else l=mid+1;
        }
        printf("%d
    ",ans);
        return 0;
    }
    /*
    数组版本  竟然跑得更快 而且不爆栈
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm> 
    #define maxn 100010
    using namespace std;
    int n,s,topt,l,r,ans,sum;
    int first[maxn];
    int f[maxn],a[maxn]; 
    struct edge
    {
        int to;
        int next;
    }e[maxn*2];
    int init()
    {
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    void add(int x,int y)
    {
        topt++;
        e[topt].to=y;
        e[topt].next=first[x];
        first[x]=topt;
    }
    void dfs(int x,int from,int limit)
    {
        int tot=0;
        for(int i=first[x];i;i=e[i].next)
        {
            int to=e[i].to;
            if(to==from)continue;
            dfs(to,x,limit);
        }
        for(int i=first[x];i;i=e[i].next)
        {
            int to=e[i].to;
            if(to==from)continue;
            a[++tot]=f[to]+1;
        }
        sort(a+1,a+tot+1);
        while(tot>0&&a[tot]+a[tot-1]>limit)tot--,sum++;
        f[x]=a[tot];
    }
    int judge(int x)
    {
        sum=0;dfs(1,0,x);
        return sum<=s;
    }
    int main()
    {
        n=init();s=init();
        for(int i=1;i<=n-1;i++)
        {
            int x,y;
            x=init();y=init();
            add(x,y);add(y,x);
        }
        l=0,r=n;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(judge(mid))
            {
                r=mid-1;
                ans=mid;
            }
            else l=mid+1;
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    Selenium简单测试页面加载速度的性能(Page loading performance)
    Selenium Page object Pattern usage
    Selenium如何支持测试Windows application
    UI Automation的两个成熟的框架(QTP 和Selenium)
    分享自己针对Automation做的两个成熟的框架(QTP 和Selenium)
    敏捷开发中的测试金字塔(转)
    Selenium 的基础框架类
    selenium2 run in Jenkins GUI testing not visible or browser not open but run in background浏览器后台运行不可见
    eclipse与SVN 结合(删除SVN中已经上传的问题)
    配置Jenkins的slave节点的详细步骤适合windows等其他平台
  • 原文地址:https://www.cnblogs.com/dingmenghao/p/6043391.html
Copyright © 2011-2022 走看看