Submission #577515

#TimeUsernameProblemLanguageResultExecution timeMemory
577515balbitCapital City (JOI20_capital_city)C++14
100 / 100
847 ms43888 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long #define pii pair<ll, ll> #define f first #define s second #define SZ(x) (int)((x).size()) #define ALL(x) (x).begin(), (x).end() #define pb push_back #define MX(a,b) a = max(a,b) #define MN(a,b) a = min(a,b) #define FOR(i,a,b) for (int i = a; i<b; ++i) #define REP(i,n) for (int i = 0; i<n; ++i) #define REP1(i,n) for (int i = 1; i<=n; ++i) #ifdef BALBIT #define bug(...) cerr<<"#"<<__LINE__<<"- "<<#__VA_ARGS__<<": ", _do(__VA_ARGS__) template<typename T> void _do(T && x){cerr<<x<<endl;} template<typename T, typename ...S> void _do(T && x, S && ...y){cerr<<x<<", "; _do(y...);} #else #define bug(...) #define endl '\n' #endif // BALBIT const int maxn = 2e5+5; const int mod = 1e9+7; bool dead[maxn]; bool colorok[maxn]; int color[maxn]; int sz[maxn]; vector<int> g[maxn]; vector<int> where[maxn]; // where are the nodes of this color? void predfs(int v, int p) { sz[v] = 1; for (int u : g[v]) { if (dead[u]) continue; if (u != p) { predfs(u,v); sz[v] += sz[u]; } } } int allsz = -1; int getcen(int v, int p) { for (int u : g[v]) { if (dead[u]) continue; if (u != p && sz[u] > (allsz)/2) { return getcen(u,v); } } return v; } int dep[maxn]; bool done[maxn]; // make sure to clear!!! bool inque[maxn]; // make sure to clear!!! int par[maxn]; vector<int> colorshere; int subtree[maxn]; // which subtree is it????? void dfs(int v, int p) { done[v] = 0; inque[color[v]] = 0; colorshere.pb(color[v]); for (int u : g[v]) { if (dead[u]) continue; if (u!=p) { dep[u] = dep[v] + 1; par[u] = v; if (p == -1) { subtree[u] = u; }else{ subtree[u] = subtree[v]; } dfs(u,v); } } } int re = maxn; void decomp(int stv, int lay) { predfs(stv, -1); allsz = sz[stv]; int cen = getcen(stv, -1); bug(stv, lay, cen); stv = -1; dep[cen] = 0; colorshere.clear(); dfs(cen, -1); sort(ALL(colorshere)); colorshere.resize(unique(ALL(colorshere)) - colorshere.begin()); done[cen] = 1; if (colorok[color[cen]]) { queue<int> q; q.push(color[cen]); inque[color[cen]] = 1; int nmerge = 0; bool bad = 0; while (!q.empty()) { int cc = q.front(); q.pop(); for (int x : where[cc]) { for (int at = x; !done[at]; at= par[at]) { done[at] = 1; int c = color[at]; if (!inque[c] && colorok[c]) { inque[c] = 1; q.push(c); ++nmerge; } if (!colorok[c]) { bad = 1; break; } } if (bad) break; } } if (!bad) { bug(nmerge); MN(re, nmerge); } } dead[cen] = 1; colorok[color[cen]] = 0; for (int t : colorshere) { if (colorok[t]) { int mn = maxn, mx = -1; for (int x : where[t]) { MN(mn, subtree[x]); MX(mx, subtree[x]); } if (mn < mx) { colorok[t] = 0; } } } for (int u : g[cen]) { if (!dead[u]) { decomp(u, lay+1); } } } signed main(){ ios::sync_with_stdio(0), cin.tie(0); bug(1,2); int n,c; cin>>n>>c; REP(i,n-1) { int a,b; cin>>a>>b; --a; --b; g[a].pb(b); g[b].pb(a); } REP(i,n) { cin>>color[i]; colorok[color[i]] = 1; where[color[i]].pb(i); } decomp(0, 0); cout<<re<<endl; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...