kaage精進録

雑な解説とかライブラリとかおきもちの垂れ流しです。

競プロ典型 90 問 026 - Independent Set on a Tree 解説

準備やりました。

問題リンク(Twitter/原案) 問題リンク(AtCoder)

解説

木は二部グラフなので、大きい方から $\frac{N}{2}$ 個取れば良いです。

サンプルコード

#include <algorithm>
#include <iostream>
#include <vector>

#define rep(i, n) for (int i = 0; i < int(n); i++)
#define REP(i, n) for (int i = 1; i <= int(n); i++)

template <class F>
inline constexpr decltype(auto) lambda_fix(F&& f) {
    return [f = std::forward<F>(f)](auto&&... args) {
        return f(f, std::forward<decltype(args)>(args)...);
    };
}
template <class T>
constexpr void printArray(const std::vector<T>& vec, char split = ' ') {
    rep(i, vec.size()) {
        std::cout << vec[i];
        std::cout << (i == (int)vec.size() - 1 ? '\n' : split);
    }
}
int N;
std::vector<int> vec[100010], ans;
int flag[100010];
int main() {
    std::cin >> N;
    rep(i, N - 1) {
        int A, B;
        std::cin >> A >> B;
        vec[A].emplace_back(B);
        vec[B].emplace_back(A);
    }
    lambda_fix([&](auto self, int node, bool f) -> void {
        flag[node] = f + 1;
        for (int i : vec[node]) {
            if (!flag[i]) self(self, i, !f);
        }
    })(1, false);
    if (std::count(flag + 1, flag + N + 1, 1) >= N / 2) {
        REP(i, N) {
            if (flag[i] == 1) ans.emplace_back(i);
            if (ans.size() == N / 2) break;
        }
        printArray(ans);
    } else {
        REP(i, N) {
            if (flag[i] == 2) ans.emplace_back(i);
            if (ans.size() == N / 2) break;
        }
        printArray(ans);
    }
    return 0;
}