Submission #216894

#TimeUsernameProblemLanguageResultExecution timeMemory
216894eriksuenderhaufCapital City (JOI20_capital_city)C++11
100 / 100
282 ms61788 KiB
//#pragma GCC optimize("O3") #include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #define trav(x,a) for (const auto& x: a) #define sz(x) (int)(x).size() #define mem(a,v) memset((a), (v), sizeof (a)) #define enl printf("\n") #define case(t) printf("Case #%d: ", (t)) #define ni(n) scanf("%d", &(n)) #define nl(n) scanf("%I64d", &(n)) #define nai(a, n) for (int _i = 0; _i < (n); _i++) ni(a[_i]) #define nal(a, n) for (int _i = 0; _i < (n); _i++) nl(a[_i]) #define pri(n) printf("%d\n", (n)) #define prl(n) printf("%I64d\n", (n)) #define pii pair<int, int> #define pll pair<long long, long long> #define vii vector<pii> #define vll vector<pll> #define vi vector<int> #define vl vector<long long> #define pb push_back #define mp make_pair #define st first #define nd second using namespace std; using namespace __gnu_pbds; typedef long long ll; typedef cc_hash_table<int,int,hash<int>> ht; typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> oset; const double pi = acos(-1); const int mod = 1e9 + 7; const int inf = 1e9 + 7; const int N = 1e6 + 5; const double eps = 1e-9; #define log2(x) (31 - __builtin_clz(x)) struct sparse_table { int n; vector<int> a; vector<vector<int>> st; int combine(int dl, int dr) { return a[dl] > a[dr] ? dl : dr; } sparse_table() {} sparse_table(vector<int> & a) : n(a.size()), a(a), st(log2(n) + 1, vector<int>(n)) { for (int i = 0; i < n; i++) st[0][i] = i; for (int j = 1; 1 << j <= n; j++) for (int i = 0; i + (1 << j) <= n; i++) st[j][i] = combine(st[j - 1][i], st[j - 1][i + (1 << (j - 1))]); } // query the data on the range [l, r[ int query(int l, int r) { int s = log2(r - l); return combine(st[s][l], st[s][r - (1 << s)]); } }; struct lowest_common_ancestor { int n, m = 0; vector<int> a, v, h, par; vector<vector<int>>& e; sparse_table st; lowest_common_ancestor(vector<vector<int>> & e, int r) : n(e.size()), a(n), v(2 * n - 1), h(2 * n - 1), e(e), par(n) { dfs(r); st = sparse_table(h); } void dfs(int i, int p = -1, int d = 0) { par[i] = p; a[i] = m; v[m] = i; h[m++] = d; for (int j : e[i]) { if (j == p) continue; dfs(j, i, d - 1); v[m] = i; h[m++] = d; } } // calculate the lowest common ancestor of x and y int lca(int x, int y) { return v[st.query(min(a[x], a[y]), max(a[x], a[y]) + 1)]; } int ok(int x, int y) { return lca(par[x], y) == y; } }; struct strongly_connected_components { int n, v = 0, c = 0; vector<bool> ins; vector<int> s, num, low, com, cnt; vector<vector<int>>& e; strongly_connected_components(vector<vector<int>> & e) : n(e.size()), ins(n), num(n, -1), low(n), com(n), e(e), cnt(n) { for (int i = 0; i < n; i++) if (num[i] == -1) dfs(i); for (int i = 0; i < n; i++) trav(x, e[i]) if (com[x] != com[i]) cnt[com[i]] = n+1; } // use commented lines for biconnected components in undirected graphs void dfs(int i) { // void dfs(int i, int p = -1) { num[i] = low[i] = v++; s.push_back(i); ins[i] = true; for (int j : e[i]) { // if (j == p) { // p = -1; // continue; // } if (num[j] == -1) dfs(j); // dfs(j, i); if (ins[j]) low[i] = min(low[i], low[j]); } if (low[i] == num[i]) { int j; do { j = s.back(); s.pop_back(); ins[j] = false; com[j] = c; cnt[c]++; } while (j != i); c++; } } }; int en[N], c[N]; // vector<int> st[N], adj[N]; vector<vector<int>> e; int main() { int n, k; scanf("%d %d", &n, &k); e.resize(n); for (int i = 1, u, v; i < n; i++) { scanf("%d %d", &u, &v); u--, v--; e[u].push_back(v); e[v].push_back(u); } for (int i = 0; i < n; i++) { scanf("%d", &c[i]); c[i]--; en[c[i]] = i; } lowest_common_ancestor l(e, 0); for (int i = 0; i < n; i++) en[c[i]] = l.lca(en[c[i]], i); vector<vector<int>> f(k); for (int i = 0; i < n; i++) { if (l.par[i] != -1 && c[i] != c[l.par[i]] && l.ok(i, en[c[i]])) { f[c[i]].pb(c[l.par[i]]); // cout << c[i]+1 << " " << c[l.par[i]]+1 << endl; } } strongly_connected_components sc(f); int ans = k-1; for (int i = 0; i < sc.c; i++) ans = min(ans, sc.cnt[i] - 1); printf("%d\n", ans); return 0; }

Compilation message (stderr)

capital_city.cpp: In constructor 'lowest_common_ancestor::lowest_common_ancestor(std::vector<std::vector<int> >&, int)':
capital_city.cpp:64:24: warning: 'lowest_common_ancestor::e' will be initialized after [-Wreorder]
   vector<vector<int>>& e;
                        ^
capital_city.cpp:63:24: warning:   'std::vector<int> lowest_common_ancestor::par' [-Wreorder]
   vector<int> a, v, h, par;
                        ^~~
capital_city.cpp:66:3: warning:   when initialized here [-Wreorder]
   lowest_common_ancestor(vector<vector<int>> & e, int r) : n(e.size()), a(n), v(2 * n - 1), h(2 * n - 1), e(e), par(n) {
   ^~~~~~~~~~~~~~~~~~~~~~
capital_city.cpp: In constructor 'strongly_connected_components::strongly_connected_components(std::vector<std::vector<int> >&)':
capital_city.cpp:93:24: warning: 'strongly_connected_components::e' will be initialized after [-Wreorder]
   vector<vector<int>>& e;
                        ^
capital_city.cpp:92:33: warning:   'std::vector<int> strongly_connected_components::cnt' [-Wreorder]
   vector<int> s, num, low, com, cnt;
                                 ^~~
capital_city.cpp:94:3: warning:   when initialized here [-Wreorder]
   strongly_connected_components(vector<vector<int>> & e) : n(e.size()), ins(n), num(n, -1), low(n), com(n), e(e), cnt(n) {
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
capital_city.cpp: In function 'int main()':
capital_city.cpp:137:18: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   int n, k; scanf("%d %d", &n, &k);
             ~~~~~^~~~~~~~~~~~~~~~~
capital_city.cpp:140:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d %d", &u, &v); u--, v--;
     ~~~~~^~~~~~~~~~~~~~~~~
capital_city.cpp:145:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d", &c[i]); c[i]--;
     ~~~~~^~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...