제출 #1009823

#제출 시각아이디문제언어결과실행 시간메모리
1009823boris_mihov봉쇄 시간 (IOI23_closing)C++17
51 / 100
50 ms51284 KiB
#include "closing.h" #include <algorithm> #include <iostream> #include <numeric> #include <cassert> #include <vector> #include <queue> typedef long long llong; const int MAXN = 2000 + 10; const llong INF = 8e18; const int INTINF = 2e9; int n; int x; int y; llong k; int sz[MAXN]; int par[MAXN]; bool isOnPath[MAXN]; std::vector <int> path; std::vector <int> pathSizes; std::vector <std::pair <int,int>> g[MAXN]; std::vector <int> suffixSizes[MAXN]; llong dpR[MAXN][2 * MAXN][2][2]; // root llong dpC[MAXN][2 * MAXN][2][2]; // children, knapsack llong dpS[MAXN][2 * MAXN][2][2]; // stick bool blR[MAXN][2 * MAXN][2][2]; bool blC[MAXN][2 * MAXN][2][2]; bool blS[MAXN][2 * MAXN][2][2]; llong distX[MAXN]; llong distY[MAXN]; void reset() { path.clear(); pathSizes.clear(); for (int i = 0 ; i < n ; ++i) { g[i].clear(); suffixSizes[i].clear(); isOnPath[i] = false; distX[i] = distY[i] = 0; for (int j = 0 ; j <= 2 * n ; ++j) { for (int flagX = 0 ; flagX < 2 ; ++flagX) { for (int flagY = 0 ; flagY < 2 ; ++flagY) { dpR[i][j][flagX][flagY] = 0; dpC[i][j][flagX][flagY] = 0; dpS[i][j][flagX][flagY] = 0; blR[i][j][flagX][flagY] = false; blC[i][j][flagX][flagY] = false; blS[i][j][flagX][flagY] = false; } } } } } void dfs(int node, int par, llong to[], llong dist) { to[node] = dist; for (const auto &[u, d] : g[node]) { if (u == par) { continue; } dfs(u, node, to, dist + d); } } bool dfsPath(int node, int par) { if (node == y) { path.push_back(node); return true; } for (const auto &[u, d] : g[node]) { if (u == par) { continue; } if (dfsPath(u, node)) { path.push_back(node); return true; } } return false; } void dfsSize(int node, int p) { sz[node] = 1; par[node] = p; for (const auto &[u, d] : g[node]) { if (p == u) { continue; } dfsSize(u, node); if (!isOnPath[u]) sz[node] += sz[u]; } } llong fRoot(int, int, int, int); llong fChildren(int, int, int, int, int); llong fStick(int, int, int, int); llong stepsRoot; llong stepsChildren; llong stepsStick; llong fRoot(int node, int choose, int flagX, int flagY) { stepsRoot++; if (choose == 0) { return 0; } if (!flagX && !flagY) { return k + 1; } if (blR[node][choose][flagX][flagY]) { return dpR[node][choose][flagX][flagY]; } blR[node][choose][flagX][flagY] = true; dpR[node][choose][flagX][flagY] = fChildren(node, 0, choose, flagX, flagY); dpR[node][choose][flagX][flagY] = std::min(dpR[node][choose][flagX][flagY], k + 1); return dpR[node][choose][flagX][flagY]; } llong fChildren(int node, int idx, int choose, int flagX, int flagY) { stepsChildren++; if (idx == g[node].size()) { if (choose == 0) return 0; return k + 1; } int current = g[node][idx].first; if (isOnPath[current] || current == par[node]) { return fChildren(node, idx + 1, choose, flagX, flagY); } if (blC[current][choose][flagX][flagY]) { return dpC[current][choose][flagX][flagY]; } blC[current][choose][flagX][flagY] = true; dpC[current][choose][flagX][flagY] = k + 1; for (int currX = 0 ; currX <= flagX ; ++currX) { for (int currY = 0 ; currY <= flagY ; ++currY) { for (int subtreeChoose = std::max(choose - (flagX + flagY) * suffixSizes[node][idx + 1], currX + currY) ; subtreeChoose <= std::min((currX + currY) * sz[g[node][idx].first], choose) ; ++subtreeChoose) { stepsChildren++; dpC[current][choose][flagX][flagY] = std::min(dpC[current][choose][flagX][flagY], fChildren(node, idx + 1, choose - subtreeChoose, flagX, flagY) + std::max((currX == 0 ? 0 : distX[current]), (currY == 0 ? 0 : distY[current])) + fRoot(current, subtreeChoose - currX - currY, currX, currY)); } } } return dpC[current][choose][flagX][flagY]; } llong fStick(int idx, int choose, int flagX, int flagY) { stepsStick++; if (idx == path.size()) { if (choose == 0) return 0; return k + 1; } if (blS[idx][choose][flagX][flagY]) { return dpS[idx][choose][flagX][flagY]; } blS[idx][choose][flagX][flagY] = true; dpS[idx][choose][flagX][flagY] = k + 1; for (int currX = 0 ; currX <= flagX ; ++currX) { for (int currY = flagY ; currY <= 1 ; ++currY) { for (int subtreeChoose = std::max(choose - 2 * pathSizes[idx + 1], currX + currY) ; subtreeChoose <= std::min(2 * sz[path[idx]], choose) ; ++subtreeChoose) { stepsStick++; int val = dpS[idx][choose][flagX][flagY]; dpS[idx][choose][flagX][flagY] = std::min(dpS[idx][choose][flagX][flagY], fStick(idx + 1, choose - subtreeChoose, currX, currY) + std::max((currX == 0 ? 0 : distX[path[idx]]), (currY == 0 ? 0 : distY[path[idx]])) + fRoot(path[idx], subtreeChoose - currX - currY, currX, currY)); } } } return dpS[idx][choose][flagX][flagY]; } int max_score(int N, int X, int Y, long long K, std::vector <int> U, std::vector <int> V, std::vector <int> W) { reset(); n = N; x = X; y = Y; k = K; for (int i = 0 ; i < n - 1 ; ++i) { g[U[i]].emplace_back(V[i], W[i]); g[V[i]].emplace_back(U[i], W[i]); } dfs(x, -1, distX, 0); dfs(y, -1, distY, 0); dfsPath(x, -1); std::reverse(path.begin(), path.end()); for (const int &i : path) { isOnPath[i] = true; } dfsSize(x, -1); for (int i = 0 ; i < n ; ++i) { suffixSizes[i].resize(g[i].size() + 1, 0); for (int j = g[i].size() - 1 ; j >= 0 ; --j) { int add = 0; suffixSizes[i][j] = suffixSizes[i][j + 1]; if (!isOnPath[g[i][j].first] && g[i][j].first != par[i]) { add = sz[g[i][j].first]; } suffixSizes[i][j] += add; } } pathSizes.resize(path.size() + 1, 0); for (int i = path.size() - 1 ; i >= 0 ; --i) { pathSizes[i] = pathSizes[i + 1] + sz[path[i]]; } for (int i = 2 * n ; i >= 1 ; --i) { if (fStick(0, i, 1, 0) <= k) { return i; } } return 0; }

컴파일 시 표준 에러 (stderr) 메시지

closing.cpp: In function 'llong fChildren(int, int, int, int, int)':
closing.cpp:151:13: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  151 |     if (idx == g[node].size())
      |         ~~~~^~~~~~~~~~~~~~~~~
closing.cpp: In function 'llong fStick(int, int, int, int)':
closing.cpp:189:13: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  189 |     if (idx == path.size())
      |         ~~~~^~~~~~~~~~~~~~
closing.cpp:209:21: warning: unused variable 'val' [-Wunused-variable]
  209 |                 int val = dpS[idx][choose][flagX][flagY];
      |                     ^~~
#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...
#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...