Submission #1279604

#TimeUsernameProblemLanguageResultExecution timeMemory
1279604icebear수도 (JOI20_capital_city)C++20
1 / 100
3098 ms53176 KiB
// ~~ icebear ~~ #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> ii; typedef pair<int, ii> iii; template<class T> bool minimize(T &a, const T &b) { if (a > b) return a = b, true; return false; } template<class T> bool maximize(T &a, const T &b) { if (a < b) return a = b, true; return false; } #define FOR(i,a,b) for(int i=(a); i<=(b); ++i) #define FORR(i,a,b) for(int i=(a); i>=(b); --i) #define REP(i, n) for(int i=0; i<(n); ++i) #define RED(i, n) for(int i=(n)-1; i>=0; --i) #define MASK(i) (1LL << (i)) #define BIT(S, i) (((S) >> (i)) & 1) #define mp make_pair #define pb push_back #define fi first #define se second #define all(x) x.begin(), x.end() #define task "gen" /*END OF TEMPLATE. ICEBEAR AND THE CAT WILL WIN VOI26 */ const int MOD = 1e9 + 7; const int inf = 1e9 + 27092008; const ll INF = 1e18 + 27092008; const int N = 2e5 + 5; int n, k; vector<int> G[N], town[N]; int par[N][20], h[N], city[N]; struct DisjointSet { vector<int> lab; DisjointSet(int n = 0): lab(n + 5, -1) {} int root(int v) { return lab[v] < 0 ? v : lab[v] = root(lab[v]); } bool unite(int u, int v) { u = root(u); v = root(v); if (u == v) return false; if (h[u] > h[v]) swap(u, v); lab[v] = u; return true; } } dsu; void dfs(int u) { for(int v : G[u]) if (v != par[u][0]) { par[v][0] = u; h[v] = h[u] + 1; dfs(v); } } int LCA(int u, int v) { if (h[u] < h[v]) swap(u, v); int s = h[u] - h[v]; RED(j, 20) if (BIT(s, j)) u = par[u][j]; if (u == v) return u; RED(j, 20) if (par[u][j] != par[v][j]) { u = par[u][j]; v = par[v][j]; } return par[u][0]; } set<int> cur_city; void connect(int u, int v) { int p = LCA(u, v); while(true) { int last = u; u = par[dsu.root(u)][0]; if (h[u] <= h[p]) break; cur_city.insert(city[u]); dsu.unite(last, u); } while(true) { int last = v; v = par[dsu.root(v)][0]; if (h[v] <= h[p]) break; cur_city.insert(city[v]); dsu.unite(last, v); } cur_city.insert(city[p]); if (p > 1) dsu.unite(p, par[p][0]); } int get_merge(int C) { dsu = DisjointSet(n); cur_city.clear(); cur_city.insert(C); for(int X : cur_city) { FOR(i, 1, (int)town[X].size() - 1) FOR(j, 0, i - 1) connect(town[X][j], town[X][i]); } return (int)cur_city.size() - 1; } void init(void) { cin >> n >> k; FOR(i, 2, n) { int u, v; cin >> u >> v; G[u].pb(v); G[v].pb(u); } FOR(i, 1, n) { cin >> city[i]; town[city[i]].pb(i); } } void process(void) { dfs(1); FOR(j, 1, 19) FOR(i, 1, n) par[i][j] = par[par[i][j - 1]][j - 1]; int ans = inf; FOR(i, 1, k) minimize(ans, get_merge(i)); cout << ans; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); if (fopen(task".inp", "r")) { freopen(task".inp", "r", stdin); freopen(task".out", "w", stdout); } int tc = 1; // cin >> tc; while(tc--) { init(); process(); } return 0; }

Compilation message (stderr)

capital_city.cpp: In function 'int main()':
capital_city.cpp:139:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  139 |         freopen(task".inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
capital_city.cpp:140:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  140 |         freopen(task".out", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...