Submission #545532

#TimeUsernameProblemLanguageResultExecution timeMemory
545532LucaDantasMergers (JOI19_mergers)C++17
100 / 100
1063 ms156236 KiB
#include <bits/stdc++.h> using namespace std; constexpr int maxn = 5e5+10, logn = 21; struct DSU { int pai[maxn], peso[maxn], sz; DSU(int n = 0, int _sz = 0) { sz = _sz; for(int i = 1; i <= n; i++) pai[i] = i, peso[i] = 1; } int find(int x) { return pai[x] == x ? x : pai[x] = find(pai[x]); } void join(int a, int b) { a = find(a), b = find(b); if(a == b) return; --sz; if(peso[a] < peso[b]) swap(a, b); pai[b] = a; peso[a] += peso[b]; } } dsu; vector<int> g[maxn]; int p[maxn][logn], depth[maxn]; void pre(int u) { for(int v : g[u]) if(v != p[u][0]) { p[v][0] = u; depth[v] = depth[u]+1; pre(v); } // printf("%d %d <- %d\n", u, depth[u], p[u][0]); } void build() { for(int l = 1; l < logn; l++) for(int u = 0; u < maxn; u++) p[u][l] = p[p[u][l-1]][l-1]; } int LCA(int a, int b) { if(depth[a] < depth[b]) swap(a, b); // a é o que sobe for(int l = logn-1; l >= 0; l--) if(depth[a] - (1 << l) >= depth[b]) a = p[a][l]; if(a == b) return a; for(int l = logn-1; l >= 0; l--) if(p[a][l] != p[b][l]) a = p[a][l], b = p[b][l]; return p[a][0]; } int lca_cor[maxn], lca[maxn], cor[maxn]; void dfs(int u) { lca[u] = lca_cor[cor[u]]; for(int v : g[u]) if(v != p[u][0]) { dfs(v); if(lca[v] == v) continue; dsu.join(cor[u], cor[v]); lca[u] = LCA(lca[u], lca[v]); } } vector<int> g_cor[maxn]; int main() { int n, k; scanf("%d %d", &n, &k); for(int i = 1, u, v; i < n; i++) scanf("%d %d", &u, &v), g[u].push_back(v), g[v].push_back(u); pre(1); build(); for(int i = 1; i <= n; i++) scanf("%d", &cor[i]); for(int i = 1; i <= n; i++) { if(!lca_cor[cor[i]]) lca_cor[cor[i]] = i; else lca_cor[cor[i]] = LCA(lca_cor[cor[i]], i); } dsu = DSU(n, k); dfs(1); int leafs = 0; for(int u = 1; u <= n; u++) for(int v : g[u]) if(dsu.find(cor[v]) != dsu.find(cor[u])) g_cor[dsu.find(cor[u])].push_back(dsu.find(cor[v])); for(int i = 1; i <= n; i++) { sort(g_cor[i].begin(), g_cor[i].end()); g_cor[i].erase(unique(g_cor[i].begin(), g_cor[i].end()), g_cor[i].end()); // if(g_cor[i].size()) { // printf("%d ==", i); // for(int x : g_cor[i]) // printf(" %d", x); // puts(""); // } } for(int i = 1; i <= n; i++) leafs += g_cor[i].size() == 1; printf("%d\n", (leafs+1)>>1); }

Compilation message (stderr)

mergers.cpp: In function 'int main()':
mergers.cpp:72:20: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   72 |     int n, k; scanf("%d %d", &n, &k);
      |               ~~~~~^~~~~~~~~~~~~~~~~
mergers.cpp:74:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   74 |         scanf("%d %d", &u, &v), g[u].push_back(v), g[v].push_back(u);
      |         ~~~~~^~~~~~~~~~~~~~~~~
mergers.cpp:79:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   79 |         scanf("%d", &cor[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...
#Verdict Execution timeMemoryGrader output
Fetching results...