• msc的宠物 二分+树形DP


    https://ac.nowcoder.com/acm/contest/7016/E

    这题真没想到

    考虑一个问题,删除边对极差的影响,-------无论如何删除边都有办法不让让答案变大(可能相等)

    利用二分答案,每次算出mid都跑一次dp看看能不能k条边以内完成,dp[x][i]表示以x为根的子树,所有点的数值在list[i] -- list[i] + mid之间最少删除dp[x][i]个边

    ans[x]表示ans[x]极差在mid之间最少删除ans[x] t条边

    具体在代码

    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using namespace std;
    const int maxn = 2000+11;
    typedef long long ll;
    ll inf = 1e15;
    ll mid;
    ll dp[maxn][maxn];
    ll list[maxn];
    
    vector<int>G[maxn];
    void add(int x,int y){
        G[x].push_back(y);
    }
    int n,k;
    ll ans[maxn];
    
    int dfs(int x,int fa){ 
    	//cout<<x<<endl;
        for(int i = 1;i<=n;i++){
            if(list[x] >= list[i] && list[i] + mid >= list[x]){
                dp[x][i] = 0;
            }
            else{
                dp[x][i] = inf;
            }
        }
        
        for(int i=0;i<G[x].size();i++){
            int p = G[x][i];
            if(p == fa) continue;
            dfs(p,x);
    
            for(int j=1;j<=n;j++){
                dp[x][j] += min(dp[p][j],ans[p] + 1);
            }
        }
        for(int i = 1;i<=n;i++){
           ans[x] = min(ans[x],dp[x][i]);
        }
        return 0;
    }
    
    int jude(){
        for(int i=0;i<=n;i++){
            ans[i] = inf;
        }
        dfs(1,-1);
        return (ans[1] <= k);//可行 
    }
    int main(){
        
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++){
        	ans[i] = inf;
            scanf("%lld",&list[i]);
        }
        
        for(int i=1;i<n;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
      	
        ll l = 0;
        ll r = 2e9+7;
        ll cns = 0;
        
        for(int i=0;i<111;i++){
            mid = (l+r)/2;
            if(jude()){//可以,区间加大
                cns = mid;
    			r = mid - 1;
            }
            else{
                l = mid + 1;
            }
        }
        
        printf("%lld
    ",cns);
        return 0;
    }
    

      

    寻找真正的热爱
  • 相关阅读:
    I/O流
    Java反编译 jar包
    springMVC配置
    Java三大特征之封装(一)
    类的实例方法
    类的构造方法
    对象与类的区别
    网站标题前的小logo
    Django 学习之CORS
    Django 学习之Celery(芹菜)
  • 原文地址:https://www.cnblogs.com/lesning/p/13532766.html
Copyright © 2020-2023  润新知