BZOJ2097 [Usaco2010 Dec] Exercise cows aerobics greedy

Topic Portal

https://lydsy.com/JudgeOnline/problem.php?id=2097

answer

Obviously a binary \ (MID \) represents the maximum diameter of the length of each block, the number of communication requires a minimum block request.

Then we found that if a legitimate diameter of the communication block without vertex communication block, then at the apex when the plus side, the diameter of the communication blocks can be ignored, because in any case can not make the long side of the original diameter. It is only necessary to consider downwardly from the apex of the longest chain on it.

So we record a \ (f [i] \) represented by \ (I \) is the chain length of the longest root block communication. Then greedy, sub-merged from the tree to the root, we will all \ (f [son] \) is sorted, then find the greatest satisfaction merge two adjacent less \ (mid \) is. The latter would require all cut off.


Code below, due to the need to sort, time complexity \ (O (n-\ log n-) \) .

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back

template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b , 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b , 1 : 0;}

typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;

template<typename I>
inline void read(I &x) {
    int f = 0, c;
    while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    x = c & 15;
    while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    f ? x = -x : 0;
}

const int N = 1e5 + 7;

int n, m, cnt;
int tt[N], f[N];

struct Edge { int to, ne; } g[N << 1]; int head[N], tot;
inline void addedge(int x, int y) { g[++tot].to = y, g[tot].ne = head[x], head[x] = tot; }
inline void adde(int x, int y) { addedge(x, y), addedge(y, x); }

inline void dfs(int x, const int &mid, int fa = 0) {
    for fec(i, x, y) if (y != fa) dfs(y, mid, x);
    tt[0] = 0, f[x] = 0;
    for fec(i, x, y) if (y != fa) tt[++tt[0]] = f[y] + 1;
    std::sort(tt + 1, tt + tt[0] + 1);
    for (int i = tt[0]; i; --i)
        if ((i == 1 && tt[i] <= mid) || tt[i] + tt[i - 1] <= mid) {
            f[x] = tt[i];
            break;
        } else ++cnt;
}

inline bool check(const int &mid) {
    cnt = 0;
    dfs(1, mid);
    return cnt <= m;
}

inline void work() {
    int l = 0, r = n - 1;
    while (l < r) {
        int mid = (l + r) >> 1;
        if (check(mid)) r = mid;
        else l = mid + 1;
    }
    printf("%d\n", l);
}

inline void init() {
    read(n), read(m);
    for (int i = 1; i < n; ++i) {
        int x, y;
        read(x), read(y);
        adde(x, y);
    }
}

int main() {
#ifdef hzhkk
    freopen("hkk.in", "r", stdin);
#endif
    init();
    work();
    fclose(stdin), fclose(stdout);
    return 0;
}

Guess you like

Origin www.cnblogs.com/hankeke/p/BZOJ2097.html