Submission #1106336

#TimeUsernameProblemLanguageResultExecution timeMemory
1106336CodeLakVNCat in a tree (BOI17_catinatree)C++17
100 / 100
382 ms37828 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define name "main" #define FOR(i, a, b) for (int i = (a); i <= (b); i++) #define FOD(i, b, a) for (int i = (b); i >= (a); i--) template <class U, class V> bool maximize(U &x, V y) { if (x < y) { x = y; return true; } return false; } template <class U, class V> bool minimize(U &x, V y) { if (x > y) { x = y; return true; } return false; } const int INF = 1e9; const int N = 2e5 + 5; int numNode, limit; vector<int> adj[N]; int child[N], centroidParent[N]; bool del[N]; int countChild(int u, int p) { child[u] = 1; for (int v : adj[u]) { if (v == p || del[v]) continue; child[u] += countChild(v, u); } return child[u]; } int findCentroid(int u, int p, int m) { for (int v : adj[u]) { if(v == p || del[v]) continue; if (child[v] > m / 2) return findCentroid(v, u, m); } return u; } int centroidDecomp(int u) { int m = countChild(u, -1); u = findCentroid(u, -1, m); del[u] = 1; for (int v : adj[u]) { if (del[v]) continue; int x = centroidDecomp(v); centroidParent[x] = u; } return u; } int high[N]; int par[20][N]; void dfs(int u) { for (int v : adj[u]) { if (v == par[0][u]) continue; high[v] = high[u] + 1; par[0][v] = u; dfs(v); } } void setup() { dfs(1); FOR(i, 1, 18) FOR(u, 1, numNode) par[i][u] = par[i - 1][par[i - 1][u]]; high[0] = -1; } int LCA(int u, int v) { if (high[u] < high[v]) swap(u, v); FOD(i, 18, 0) if (high[par[i][u]] >= high[v]) u = par[i][u]; if (u == v) return u; FOD(i, 18, 0) if (par[i][u] != par[i][v]) { u = par[i][u]; v = par[i][v]; } return par[0][u]; } int dist(int u, int v) { return high[u] + high[v] - 2 * high[LCA(u, v)]; } bool cmp(int &x, int &y) { return high[x] > high[y]; } int minDistFromCentroid[N]; int getDistToSet(int u) { int curMinDist = INF; int centroid = u; while (centroid != 0) { minimize(curMinDist, dist(centroid, u) + minDistFromCentroid[centroid]); centroid = centroidParent[centroid]; } return curMinDist; } void addToSet(int u) { int centroid = u; while (centroid != 0) { minimize(minDistFromCentroid[centroid], dist(centroid, u)); centroid = centroidParent[centroid]; } } int main() { ios_base::sync_with_stdio(NULL); cin.tie(0); cout.tie(0); if (fopen(name".inp", "r")) { freopen(name".inp", "r", stdin); freopen(name".out", "w", stdout); } cin >> numNode >> limit; FOR(i, 2, numNode) { int u; cin >> u; u++; adj[u].push_back(i); adj[i].push_back(u); } int root = centroidDecomp(1); centroidParent[root] = 0; vector<int> nodes; FOR(u, 1, numNode) nodes.push_back(u); setup(); sort(nodes.begin(), nodes.end(), cmp); memset(minDistFromCentroid, 0x3f, sizeof(minDistFromCentroid)); int ans = 0; for (int u : nodes) if(getDistToSet(u) >= limit) { ans++; addToSet(u); } cout << ans; return 0; } // Lak lu theo dieu nhac ^.^

Compilation message (stderr)

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