제출 #1332321

#제출 시각아이디문제언어결과실행 시간메모리
1332321MisterReaper수도 (JOI20_capital_city)C++20
100 / 100
376 ms30980 KiB
#include <bits/stdc++.h>

using i64 = long long;

#ifdef DEBUG
    #include "debug.h"
#else
    #define debug(...) void(23)
#endif

int main() {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int N, K;
    std::cin >> N >> K;

    std::vector<std::vector<int>> adj(N);
    for (int i = 1; i < N; ++i) {
        int U, V;
        std::cin >> U >> V;
        --U, --V;
        adj[U].emplace_back(V);
        adj[V].emplace_back(U);
    }

    std::vector<int> C(N);
    for (int i = 0; i < N; ++i) {
        std::cin >> C[i];
        --C[i];
    }

    std::vector<std::vector<int>> gs(K);
    for (int i = 0; i < N; ++i) {
        gs[C[i]].emplace_back(i);
    }

    int ans = K;

    std::vector<int> par(N);
    std::vector<int> cnt(K);
    std::vector<int> vis(K);
    std::vector<int> siz(N);
    std::vector<int> act(N, true);
    auto calc_siz = [&](auto&& self, int v) -> void {
        siz[v] = 1;
        cnt[C[v]] = 0;
        vis[C[v]] = false;
        for (auto u : adj[v]) {
            if (u == par[v] || !act[u]) {
                continue;
            }
            par[u] = v;
            self(self, u);
            siz[v] += siz[u];
        }
    };
    auto get_centroid = [&](auto&& self, int v, int tot) -> int {
        for (auto u : adj[v]) {
            if (u == par[v] || !act[u]) {
                continue;
            }
            if (siz[u] * 2 > tot) {
                return self(self, u, tot);
            }
        }
        return v;
    };
    auto dfs = [&](auto&& self, int v) -> void {
        cnt[C[v]] += 1;
        for (auto u : adj[v]) {
            if (u == par[v] || !act[u]) {
                continue;
            }
            par[u] = v;
            self(self, u);
        }
    };
    auto decomp = [&](auto&& self, int v) -> void {
        par[v] = -1;
        calc_siz(calc_siz, v);
        v = get_centroid(get_centroid, v, siz[v]);
        par[v] = -1;
        dfs(dfs, v);
        debug(v);
        std::queue<int> que;
        int now = 0;
        auto insert_color = [&](auto c) -> void {
            if (vis[c]) {
                return;
            }
            vis[c] = true;
            if (cnt[c] != gs[c].size()) {
                now = K;
                return;
            }
            now += 1;
            for (auto i : gs[c]) {
                que.emplace(i);
            }
        };
        insert_color(C[v]);
        while (!que.empty()) {
            auto i = que.front();
            que.pop();
            if (i != v) {
                insert_color(C[par[i]]);
            }
        }
        debug(now);
        ans = std::min(ans, now - 1);
        act[v] = false;
        for (auto u : adj[v]) {
            if (!act[u]) {
                continue;
            }
            self(self, u);
        }
    };
    decomp(decomp, 0);

    std::cout << ans << '\n';

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...