이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
/**
* Notes during contest.
*
* ------ A ------
* In the example, (3,7,6,6) is the set of optimal pillars to select. Well, I assume
* that the subset of pillars shall be connected in order? First, sum all costs of
* pillars. The cost of pillars that are used will then be deducted from the total.
* Our dp formula is:
* dp[k] = min( dp[i] + (h[k] - h[i])^2 - c[k])
* = min( (dp[i] + h[i]^2) - 2h[i] * h[k] ) + (h[k]^2 - c[k])
* This looks like sth that can be solved with dynamic convex hull trick. IMO this
* is like the only way to AC this problem. Unfortunately, I don't know how to code
* one using std::set<>, nor do I know LiChao tree. Maybe I'll just head to problem
* C.
*
* ------ B ------
* [S1-2] is solvable with a O(n^2) dp (Z-array + dp). I also have a hunch that we
* can pass [S3] too (#time_limit = 10s). Oh no... I really suck at str processing
* problems... I guess 60 points would be my limit.
*
* ------ C ------
* Can we score some partials here? Clearly, when Tom visits the route, only the
* last node has pigeons, so #pigeons_Tom_meets = #last_node_in_route. OK. Let V be
* the set of nodes in the route, so |V| <= v and
* #pigeons_Tom_meets = sum{ p_i : i is adjacent to at least one node in V
* or i is in V }.
* We also know that #pigeons_Jerry_meets = p_i where i is the first node. This means
* we can solve [S1-3]. Looks like DFS + dp on tree is good enough to solve the whole
* problem!
* --------------------------------- After contest ---------------------------------
* I totally misunderstood the problem... Took me over an hour in the contest.. The
* stuff above is wrong...
*
* Time Complexity 1: O(n^2)
* Time Complexity 2: O(n^2)
* Time Complexity 3: O(n^2 * v)
* Implementation 0.5 (brute-force first)
*/
#include <bits/stdc++.h>
typedef int64_t int_t;
typedef std::vector<int_t> vec;
const int_t INF = 0x3f3f3f3f3f3f3f;
const int_t N_MAX = 1e5;
const int_t V_MAX = 100;
int_t n, v;
std::vector<vec> tree;
vec pigs; // Short form for pigeons. lol
int_t dp[N_MAX][V_MAX + 1];
vec adj_sum;
int_t search(int_t src) {
std::vector<bool> visited(n, false);
visited[src] = true;
std::queue<int_t> bfs_queue;
bfs_queue.emplace(src);
dp[src][0] = 0, dp[src][1] = adj_sum[src];
for (int_t i = 2; i <= v; i++)
dp[src][i] = -INF;
int_t max = 0;
while (!bfs_queue.empty()) {
int_t t = bfs_queue.front();
bfs_queue.pop();
for (int_t k = 0; k <= v; k++)
max = std::max(max, dp[t][k]);
for (int_t neighb : tree[t]) {
if (!visited[neighb]) {
visited[neighb] = true;
for (int_t i = 0; i <= v; i++) {
dp[neighb][i] = dp[t][i];
if (i > 0) {
dp[neighb][i] = std::max(dp[neighb][i],
dp[t][i - 1] + adj_sum[neighb] - pigs[t]);
}
}
bfs_queue.emplace(neighb);
}
}
}
return max;
}
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(NULL);
std::cin >> n >> v;
tree.assign(n, vec());
pigs.resize(n);
for (int_t k = 0; k < n; k++)
std::cin >> pigs[k];
for (int_t _ = 0; _ < n - 1; _++) {
int_t a, b;
std::cin >> a >> b;
a--, b--;
tree[a].push_back(b);
tree[b].push_back(a);
}
adj_sum.resize(n);
for (int_t k = 0; k < n; k++) {
adj_sum[k] = 0;
for (int_t neighb : tree[k])
adj_sum[k] += pigs[neighb];
}
if (n <= 1000) {
int_t ans = 0;
for (int_t k = 0; k < n; k++)
ans = std::max(ans, search(k));
std::cout << ans << '\n';
} else {
std::cout << search(0) << '\n';
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |