Submission #1257022

#TimeUsernameProblemLanguageResultExecution timeMemory
1257022noyancanturkCapital City (JOI20_capital_city)C++20
11 / 100
3095 ms40488 KiB
#include<bits/stdc++.h> using namespace std; #define pb push_back using pii=pair<int,int>; const int lim=2e5+100; vector<int>v[lim]; int a[lim]; int ans; int tin[lim],tout[lim],tt=1; int parent[lim]; void dfs(int node,int par){ parent[node]=par; tin[node]=tt++; for(int j:v[node]){ if(j==par)continue; dfs(j,node); } tout[node]=tt-1; } struct comp{ bool operator()(int x,int y)const { return tin[x]<tin[y]; } }; set<int,comp>st; int vis[lim]; int tot; int sz[lim]; int sbs(int node,int par){ sz[node]=1; for(int j:v[node]){ if(j==par||vis[j])continue; sz[node]+=sbs(j,node); } return sz[node]; } int findcen(int node,int par){ for(int j:v[node]){ if(j!=par&&!vis[j]&&2*sz[j]>tot)return findcen(j,node); } return node; } unordered_map<int,int>cnt; unordered_set<int>taken; vector<int>guys[lim]; void calccnt(int node,int par){ cnt[a[node]]++; for(int j:v[node]){ if(j==par||vis[j])continue; calccnt(j,node); } } void decomp(int node){ tot=sbs(node,0); node=findcen(node,0); cnt.clear(); calccnt(node,0); if(cnt[a[node]]==guys[a[node]].size()){ taken.clear(); st.clear(); queue<int>need; unordered_set<int>cols; cols.insert(a[node]); for(int j:guys[a[node]]){ need.push(j); } int head=need.front(); need.pop(); taken.insert(head); // cerr<<"head is "<<head<<'\n'; // cerr<<"can get "; for(int j:v[head]){ if(j!=parent[head]&&!vis[j]&&!taken.count(j)){ // cerr<<j<<' '; st.insert(j); } } // cerr<<'\n'; int cant=0; while(need.size()&&!cant){ int totake=need.front(); need.pop(); while(!taken.count(totake)&&!cant){ if(!st.size()||tin[totake]<tin[*st.begin()]||tin[totake]>tout[*st.rbegin()]){ if(!parent[head]||vis[parent[head]]){ cant=1; break; }else{ head=parent[head]; if(cnt[a[head]]!=guys[a[head]].size()){ cant=1; break; } if(!cols.count(a[head])){ cols.insert(a[head]); for(int j:guys[a[head]]){ need.push(j); } } // cerr<<"took old parent "<<head<<'\n'; taken.insert(head); for(int j:v[head]){ if(j!=parent[head]&&!vis[j]&&!taken.count(j)){ st.insert(j); } } } }else{ auto p=prev(st.upper_bound(totake)); int guy=*p; if(cnt[a[guy]]!=guys[a[guy]].size()){ cant=1; break; } if(!cols.count(a[guy])){ cols.insert(a[guy]); for(int j:guys[a[guy]]){ need.push(j); } } // cerr<<"took old fashion "<<guy<<'\n'; taken.insert(guy); for(int j:v[guy]){ if(j!=parent[guy]&&!vis[j]&&!taken.count(j)){ st.insert(j); } } } } } if(!cant){ // cerr<<"found one\n"; // cerr<<"cols :: "; // for(int i:cols)cerr<<i<<' '; // cerr<<'\n'; // cerr<<"taken :: "; // for(int i:taken)cerr<<i<<' '; // cerr<<'\n'; ans=min<int>(ans,cols.size()-1); } } vis[node]=1; for(int j:v[node]){ if(!vis[j]){ decomp(j); } } } int main(){ int n,__; cin>>n>>__; for(int i=0;i<n-1;i++){ int x,y; cin>>x>>y; v[x].pb(y); v[y].pb(x); } for(int i=1;i<=n;i++){ cin>>a[i]; guys[a[i]].pb(i); } ans=n; dfs(1,0); decomp(1); 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...