제출 #1332309

#제출 시각아이디문제언어결과실행 시간메모리
1332309MisterReaperMergers (JOI19_mergers)C++20
100 / 100
632 ms106568 KiB
#include <bits/stdc++.h>

using i64 = long long;

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

struct DSU {
    std::vector<int> f, siz;
    DSU(int n) : f(n), siz(n, 1) {
        std::iota(f.begin(), f.end(), 0);
    }
    int get(int x) {
        while (x != f[x]) {
            x = f[x] = f[f[x]];
        }
        return x;
    }
    bool unite(int a, int b) {
        a = get(a), b = get(b);
        if (a == b) {
            return false; 
        } 
        f[a] = b;
        siz[b] += siz[a];
        return true;
    }
    bool same(int a, int b) {
        return get(a) == get(b);
    }
    int size(int x) {
        return siz[get(x)];
    }
};

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>> g(K);
    for (int i = 0; i < N; ++i) {
        g[C[i]].emplace_back(i);
    }

    int tim = 0;
    std::vector<int> par(N);
    std::vector<int> dep(N);
    std::vector<int> tin(N);
    auto dfs = [&](auto&& self, int v) -> void {
        tin[v] = tim++;
        for (auto u : adj[v]) {
            if (u == par[v]) {
                continue;
            }
            dep[u] = dep[v] + 1;
            par[u] = v;
            self(self, u);
        }
    };
    dfs(dfs, 0);

    DSU dsu(N);
    for (int i = 0; i < K; ++i) {
        std::sort(g[i].begin(), g[i].end(), [&](auto lhs, auto rhs) {
            return tin[lhs] < tin[rhs];
        });
        for (int j = 0; j + 1 < int(g[i].size()); ++j) {
            int v = g[i][j];
            int u = g[i][j + 1];
            while (v != u) {
                if (dep[v] < dep[u]) {
                    std::swap(u, v);
                }
                dsu.unite(v, par[v]);
                v = dsu.get(par[v]);
            }
        }
    }

    if (dsu.size(0) == N) {
        std::cout << "0\n";
        return 0;
    }

    std::vector<std::vector<int>> ndj(N);
    for (int i = 0; i < N; ++i) {
        for (auto j : adj[i]) {
            if (!dsu.same(i, j)) {
                ndj[dsu.get(i)].emplace_back(dsu.get(j));
            }
        }
    }

    int cnt = 0;
    for (int i = 0; i < N; ++i) {
        cnt += int(ndj[i].size()) == 1;
    }

    int ans = (cnt + 1) / 2;

    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...
#Verdict Execution timeMemoryGrader output
Fetching results...