• P3000 [USACO10DEC]Cow Calisthenics G


    二分 + (dp) 的好题。

    首先,要求最大直径最小,我们肯定会想到二分最大直径。 难点就在于怎么 (check)。由于正确性过于显然,二分可行性证明就略了吧。

    记录数组 (dp_u) 表示在 (u) 号点,其子树中所有点到达 (u) 号点的最大链长。转移时,考虑其和子树之间的关系。

    可以发现,(u) 号点就类似于一个 (lca),两个最长的儿子拼起来的最长链就是这棵子树的最大直径。注意,这里的 (dp_v) 中所存最长链均已保证子树内部合法。

    接着考虑子树中直径超过二分的上限怎么办?贪心地想,我们肯定是要断掉最长的那条链,保留次长的。因为这样可以使得我们的总长度尽可能小,从而达到最优次数。
    最后,如果必须断边的次数大于上限 (s), 则不合格,应该调大区间,否则一定合格。想一想为什么。(题目中不是要求我们断掉 (s) 条边吗

    具体实现看代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define N 1000010
    const int inf = 2e9; 
    
    template <class T>
    inline void read(T& a){
        T x = 0, s = 1;
        char c = getchar();
        while(!isdigit(c)){ if(c == '-') s = -1; c = getchar(); }
        while(isdigit(c)){ x = x * 10 + (c ^ '0'); c = getchar(); }
        a = x * s;
        return ; 
    }
    
    struct node{
        int v, next;
    } t[N << 1];
    int f[N];
    
    int bian = 0;
    inline void add(int u, int v){
        t[++bian] = (node){v, f[u]}, f[u] = bian;
        return ; 
    }
    
    int n, s;
    int dp[N];
    int sum = 0;   // 断了多少次 
    
    void dfs(int now, int father, int lim){
        int maxn = 0, minn = inf; 
        for(int i = f[now]; i; i = t[i].next){
            int v = t[i].v;
            if(v == father) continue; 
            dfs(v, now, lim); 
            if(dp[v] + maxn > lim) sum++, maxn = min(maxn, dp[v]);   // 保留最小值
            else maxn = max(maxn, dp[v]);     // 否则更新成最大值
        }
        dp[now] = maxn + 1; 
        return ; 
    }
    
    bool check(int lim){
        sum = 0;   // 记得清空 
        dfs(1, 0, lim);
        return sum <= s; 
    }
    
    int main(){
        read(n); read(s); 
        for(int i = 1; i < n; i++){
            int x, y;
            read(x), read(y);
            add(x, y); add(y, x); 
        }
        int l = 1, r = n, ans = 0;   // 最多断 n 次 
        while(l <= r){
            int mid = l + r >> 1;
            if(check(mid)) ans = mid, r = mid - 1;
            else l = mid + 1; 
        }
        cout << ans << endl;
        return 0; 
    }
    
  • 相关阅读:
    sql注入-原理&防御
    vulnhub靶场之AI-WEB1.0渗透记录
    python -m http.server 搭建一个简易web下载服务器
    渗透测试工具-sqlmap
    OSI七层模型
    LAXCUS大数据操作系统3.03版本发布,欢迎使用试用
    松耦合和紧耦合的架构设计、性能对比
    Laxcus大数据操作系统2.0(5)- 第二章 数据组织
    从AlphaGo谈通用型人工智能设计
    基于深度推理、自编程、大数据的通用人工智能
  • 原文地址:https://www.cnblogs.com/wondering-world/p/14075104.html
Copyright © 2020-2023  润新知