• [bzoj 2097]奶牛健美操


    题目描述

    对于一棵n个点的树,删除k条边,使得所有联通块直径最大值最小

    题解

    首先二分联通块直径最大值的最小值。

    那么这个能否达成的判定变成了一个类似树形dp的东西

    对于一个子树,删除一条边可以删除整个子树

    对于所有子树,从到达最优答案时的深度,最大的开始删除,如果当前最大值+次大值<=k时退出循环

    那么有一个二分的log  加上每次转移的sort,复杂度就是n$log$^2n

    #include<map>
    #include<stack>
    #include<queue>
    #include<cstdio>
    #include<string>
    #include<vector>
    #include<cstring>
    #include<complex>
    #include<iostream>
    #include<assert.h>
    #include<algorithm>
    using namespace std;
    #define inf 1001001001
    #define infll 1001001001001001001LL
    #define ll long long
    #define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl
    #define gmax(a,b) (a)=max((a),(b))
    #define gmin(a,b) (a)=min((a),(b))
    #define Ri register int
    #define gc getchar()
    #define il inline
    il int read(){
        bool f=true;Ri x=0;char ch;while(!isdigit(ch=gc))if(ch=='-')f=false;while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=gc;}return f?x:-x;
    }
    #define gi read()
    #define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
    struct edge{
        int to,next;
    }e[233333];
    int last[100005],ecnt,cnt,n,k,lb,rb,mid,ans;
    int f[100005],_a,a[100005];
    int dfs(int x,int fa=0){
        f[x]=0;
        //...
        for(int i=last[x];i;i=e[i].next)if(e[i].to!=fa)dfs(e[i].to,x);
        _a=a[0]=0;
        for(int i=last[x];i;i=e[i].next)if(e[i].to!=fa)a[++_a]=f[e[i].to]+1;
        sort(a+1,a+_a+1);
        while(_a&&a[_a]+a[_a-1]>mid)_a--,ans++;
        f[x]=a[_a];
    }
    bool chk(){
        ans=0;
        dfs(1);
        return ans<=k;
    }
    int main(){
        n=gi;k=gi;
        for(int i=1;i<n;i++){
            int a=gi,b=gi;
            e[++ecnt]=(edge){b,last[a]};last[a]=ecnt;
            e[++ecnt]=(edge){a,last[b]};last[b]=ecnt;        
        }
        int ans=n,lb=1,rb=n;
        while(lb<=rb){
            mid=(lb+rb)/2;
            if(chk()){
                ans=mid;
                rb=mid-1;
            }else{
                lb=mid+1;
            }
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    Linux Commands
    sizeof操作符的使用详解
    在Vim中使用cscope
    MySQL学习笔记
    Online judge for leetcode
    使用Vim,让你工作效率更高
    Ext JS笔记
    安装J2EE开发环境
    这些都是什么啊
    QrCode二维码的实现原理
  • 原文地址:https://www.cnblogs.com/chouti/p/5860274.html
Copyright © 2020-2023  润新知