제출 #1222315

#제출 시각아이디문제언어결과실행 시간메모리
1222315LucaIlie봉쇄 시간 (IOI23_closing)C++17
43 / 100
134 ms54772 KiB
#include "closing.h" #include <bits/stdc++.h> using namespace std; struct edge { int u, v, c; int other(int x) { return u ^ v ^ x; } }; struct aaa { int t, v; long long c; bool operator < (const aaa &x) const { return x.c < c; } }; const int MAX_N = 2e5; edge edges[MAX_N]; vector<int> adj[MAX_N]; int parent[MAX_N]; vector<int> path; vector<int> subtree[MAX_N]; bool onPath[MAX_N]; int level[MAX_N]; long long distX[MAX_N], distY[MAX_N]; long long cost1[MAX_N], upgrade[MAX_N]; long long paid[MAX_N]; void calcDist(int u, int p, long long dist[]) { // printf("aa %d %d %lld\n", u, p, dist[u]); parent[u] = p; for (int e: adj[u]) { int v = edges[e].other(u), c = edges[e].c; if (v == p) continue; dist[v] = dist[u] + c; calcDist(v, u, dist); } } void findSubtree(int u, int p, int w) { subtree[w].push_back(u); for (int e: adj[u]) { int v = edges[e].other(u); if (v == p || onPath[v]) continue; findSubtree(v, u, w); } } int max_score(int n, int x, int y, long long k, vector<int> U, vector<int> V, vector<int> W) { for (int v = 0; v < n; v++) { adj[v].clear(); subtree[v].clear(); parent[v] = 0; distX[v] = distY[v] = 0; onPath[v] = false; path.clear(); } for (int e = 0; e < n - 1; e++) { adj[U[e]].push_back(e); adj[V[e]].push_back(e); edges[e] = {U[e], V[e], W[e]}; } calcDist(x, -1, distX); calcDist(y, -1, distY); int v = x; while (v != y) { path.push_back(v); onPath[v] = true; v = parent[v]; } path.push_back(y); onPath[y] = true; int m = path.size(); for (int v = 0; v < n; v++) { cost1[v] = min(distX[v], distY[v]); upgrade[v] = max(distX[v], distY[v]) - cost1[v]; } for (int i = 0; i < m; i++) findSubtree(path[i], -1, path[i]); // for (int v = 0; v < n; v++) // printf("%d %lld %lld\n", v, distX[v], distY[v]); // for (int v = 0; v < n; v++) // printf("%d %lld %lld\n", v, cost1[v], upgrade[v]); int lastX = 0; for (int i = 0; i < m; i++) { int v = path[i]; if (distX[v] <= distY[v]) lastX = i; } int maxScore = 0; for (int takeAllX = 0; takeAllX < 2; takeAllX++) { for (int takeAllY = 0; takeAllY < 2; takeAllY++) { if (takeAllX != takeAllY) continue; for (int v = 0; v < n; v++) level[v] = 0; int score = 0; long long c = 0; if (takeAllX) { for (int i = 0; i <= lastX; i++) { int v = path[i]; c += distX[v]; level[v] = 1; score++; } } if (takeAllY) { for (int i = lastX + 1; i < m; i++) { int v = path[i]; c += distY[v]; level[v] = 1; score++; } } priority_queue<aaa> pq; for (int v = 0; v < n; v++) { // printf("%d %d\n", v, level[v]); if (level[v] == 0) pq.push({1, v, cost1[v]}); else if (((distX[v] <= distY[v] && takeAllY) || (distX[v] > distY[v] && takeAllX))) pq.push({2, v, upgrade[v]}); } if (c > k) continue; while (!pq.empty() && c + pq.top().c <= k) { auto p = pq.top(); pq.pop(); // printf("%d %d %lld\n", p.t, p.v, p.c); int v = p.v; c += p.c; level[v] = p.t; score++; if (level[v] == 1 && ((distX[v] <= distY[v] && takeAllY) || (distX[v] > distY[v] && takeAllX))) pq.push({2, v, upgrade[v]}); } maxScore = max(maxScore, score); // printf("%d %d -> %d\n", takeAllX, takeAllY, score); } } for (int v = 0; v < n; v++) { adj[v].clear(); subtree[v].clear(); parent[v] = 0; distX[v] = distY[v] = 0; onPath[v] = false; path.clear(); } return maxScore; }
#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...