• Luogu 3698 [CQOI2017]小Q的棋盘


    BZOJ 4813

    虽然数据范围很迷人,但是想树形$dp$没有前途。

    先发现一个事情,就是我们可以先选择一条链,最后要走到这一条链上不回来,走到链上的点每一个只需要一步,而如果要走这条链之外的点,一个点需要走两步。

    这条链怎么选取?为了尽量减少步数,肯定是最长链。

    现在有了一个显然的事情,如果限制步数$stp$不比最长链长度$mx$大的话,那么直接在最长链上走一走就好了,答案为$stp + 1$。

    一棵树最少需要$mx + 2 * (n - mx - 1) = 2n - mx - 2$步走完,如果$stp$不小于这个值,那么一定能走完,答案为$n$。

    剩下的情况只要先考虑走完最长链然后尽量分配步数到别的点上去就好了,答案为$mx + 1 + left lfloor frac{stp - mx}{2} ight floor$。

    时间复杂度$O(n)$。

    应该也有$dp$的办法吧。

    Code:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    const int N = 105;
    
    int n, stp, tot = 0, head[N], dep[N];
    
    struct Edge {
        int to, nxt;
    } e[N << 1];
    
    inline void add(int from, int to) {
        e[++tot].to = to;
        e[tot].nxt = head[from];
        head[from] = tot;
    }
    
    inline void read(int &X) {
        X = 0; char ch = 0; int op = 1;
        for(; ch > '9' || ch < '0'; ch = getchar())
            if(ch == '-') op = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            X = (X << 3) + (X << 1) + ch - 48;
        X *= op;
    }
    
    inline void chkMax(int &x, int y) {
        if(y > x) x = y;
    }
    
    void dfs(int x, int fat, int depth) {
        dep[x] = depth;
        for(int i = head[x]; i; i = e[i].nxt) {
            int y = e[i].to;
            if(y == fat) continue;
            dfs(y, x, depth + 1);
        }
    }
    
    int main() {
        read(n), read(stp);
        for(int x, y, i = 1; i < n; i++) {
            read(x), read(y);
            ++x, ++y;
            add(x, y), add(y, x);
        }
        
        dfs(1, 0, 1);
        int mx = 0;
        for(int i = 1; i <= n; i++)
            chkMax(mx, dep[i] - 1);
        
        if(stp <= mx) 
            return printf("%d
    ", stp + 1), 0;
        if(stp >= 2 * n - mx - 2) 
            return printf("%d
    ", n), 0;
        
        printf("%d
    ", mx + 1 + (stp - mx) / 2);
        return 0; 
    }
    View Code
  • 相关阅读:
    Grodno 2015 (Urozero May 2015 Day 5) D Triangles
    Flea Circus(Project Euler 213)
    Prime triplets (Project Euler 196)
    ACM 博弈(难)题练习 (第二弹)
    Crosses Puzzles zoj 4018 (zju校赛)
    Petrozavodsk Summer-2015. Ivan Smirnov Contest 1 B Bloom
    ACM 博弈(难)题练习 (第一弹)
    2017 ACM区域赛(南宁站) 参赛流水账
    2017 CCPC 杭州 流水账
    2017 ACM区域赛(西安) 参赛流水账
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9852755.html
Copyright © 2020-2023  润新知