Submission #1196686

#TimeUsernameProblemLanguageResultExecution timeMemory
1196686rxlfd314Capital City (JOI20_capital_city)C++20
0 / 100
404 ms30652 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; using ari2 = array<int, 2>; using ari3 = array<int, 3>; using arl2 = array<ll, 2>; using arl3 = array<ll, 3>; template <class T> using vt = vector<T>; #define all(x) begin(x), end(x) #define size(x) (int((x).size())) #define REP(a,b,c,d) for(int a=(b);(d)>0?a<=(c):a>=(c);a+=(d)) #define FOR(a,b,c) REP(a,b,c,1) #define ROF(a,b,c) REP(a,b,c,-1) struct DSU { vt<int> uf; DSU(const int n) : uf(n, -1) {} int find(const int i) { return uf[i] < 0 ? i : uf[i] = find(uf[i]); } bool unite(int a, int b) { if ((a = find(a)) == (b = find(b))) return false; if (uf[a] > uf[b]) swap(a, b); uf[a] += uf[b]; uf[b] = a; return true; } void reset(const int i) { uf[i] = -1; } }; signed main() { #ifndef DEBUG ios_base::sync_with_stdio(false); cin.tie(nullptr); #endif int N, K; cin >> N >> K; vt<vt<int>> adj(N); FOR(_, 2, N) { int a, b; cin >> a >> b, a--, b--; adj[a].push_back(b); adj[b].push_back(a); } vt<int> C(N), cnt(N); FOR(i, 0, N-1) { cin >> C[i], C[i]--; cnt[C[i]]++; } vt<int> dead(N), szs(N), nodes, parent(N); int ans = N; auto dfs_szs = [&](auto &&self, const int i, const int p) -> void { szs[i] = 1; nodes.push_back(i); for (const auto &j : adj[i]) { if (j == p || dead[j]) continue; self(self, j, i); szs[i] += szs[j]; } }; auto centroid = [&](int i, const int n) { int p = -1; bool flag = true; while (flag) { flag = false; for (const auto &j : adj[i]) if (j != p && !dead[j] && 2 * szs[j] > n) { p = i; i = j; flag = true; break; } } return i; }; auto dfs_par = [&](auto &&self, const int i, const int p) -> void { parent[i] = p; for (const auto &j : adj[i]) if (j != p && !dead[j]) self(self, j, i); }; vt<vt<int>> ind_list(K); vt<int> seen(N); DSU uf(K); auto dfs = [&](auto &&self, const int root) -> void { dfs_szs(dfs_szs, root, -1); const int c = centroid(root, szs[root]); dfs_par(dfs_par, c, -1); #ifdef DEBUG cout << "centroid: " << c + 1 << '\n'; #endif for (const auto &i : nodes) ind_list[C[i]].push_back(i); queue<int> qu; for (const auto &i : ind_list[C[c]]) qu.push(i), seen[i] = 1; bool good = 1; int res = 0; while (size(qu) && good) { const int i = qu.front(); qu.pop(); good &= size(ind_list[C[i]]) == cnt[C[i]]; if (parent[i] >= 0 && !seen[parent[i]] && uf.unite(C[i], C[parent[i]])) { res++; for (const auto &j : ind_list[C[parent[i]]]) { seen[j] = 1; qu.push(j); } } } if (good) ans = min(ans, res); for (const auto &i : nodes) { uf.reset(C[i]); ind_list[C[i]].clear(); } nodes.clear(); dead[c] = 1; for (const auto &j : adj[c]) if (!dead[j]) self(self, j); }; dfs(dfs, 0); cout << ans << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...