Skip to content

Commit 9176232

Browse files
committed
feat: 仍然无法解决 2021f/lab08-G
GPT5真的能秒 ICPC-2025 吗? Signed-off-by: Certseeds <51754303+Certseeds@users.noreply.github.com>
1 parent 6e9fccd commit 9176232

43 files changed

Lines changed: 276 additions & 3 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

algorithm/2021F/lab_08/lab_08_G/README.md

Lines changed: 1 addition & 1 deletion

algorithm/2021F/lab_08/lab_08_G/main.cpp

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// SPDX-FileCopyrightText: 2020-2025 nanoseeds
33
#include <algorithm>
44
#include <cstdint>
5+
#include <cstdlib>
6+
#include <ctime>
57
#include <iostream>
68
#include <memory>
79
#include <tuple>
@@ -84,13 +86,15 @@ struct ProblemInput {
8486
i32 n;
8587
i32 m;
8688
std::shared_ptr<tree::Graph> graph;
89+
i64 total_weight;
8790
};
8891

8992
using ProblemOutput = i64;
9093

9194
ProblemInput read_input();
9295
ProblemOutput solve(const ProblemInput &in);
9396
void write_output(const ProblemOutput &out);
97+
static bool can_form_paths(const ProblemInput &in, const i64 limit);
9498

9599
int main() {
96100
const auto in = read_input();
@@ -106,21 +110,110 @@ ProblemInput read_input() {
106110
int32_t v;
107111
int64_t w;
108112
in.graph = std::make_shared<tree::Graph>(in.n, static_cast<int32_t>((in.n - 1) * 2));
113+
in.total_weight = 0;
109114
for (i32 i = 0; i < in.n - 1; ++i) {
110115
std::cin >> u >> v >> w;
111-
in.graph->add_undirected_edge(u,v,w);
116+
in.graph->add_undirected_edge(u, v, w);
117+
in.total_weight += w;
112118
}
113119
return in;
114120
}
115121

116122

117123
ProblemOutput solve(const ProblemInput &in) {
124+
i64 left = 0;
125+
i64 right = in.total_weight;
126+
i64 answer = 0;
127+
while (left <= right) {
128+
const auto mid = (left + right) >> 1;
129+
if (can_form_paths(in, mid)) {
130+
answer = mid;
131+
left = mid + 1;
132+
} else {
133+
right = mid - 1;
134+
}
135+
}
136+
return answer;
118137
}
119138

120139
void write_output(const ProblemOutput &out) {
121140
std::cout << out << end;
122141
}
123142

143+
static bool can_form_paths(const ProblemInput &in, const i64 limit) {
144+
if (limit <= 0) return true;
145+
const auto &graph = *in.graph;
146+
const auto n = in.n;
147+
std::vector<int32_t> parent(static_cast<size_t>(n + 1), 0);
148+
std::vector<int32_t> order;
149+
order.reserve(static_cast<size_t>(n));
150+
std::vector<int32_t> stack;
151+
stack.reserve(static_cast<size_t>(n));
152+
stack.push_back(1);
153+
parent[1] = 0;
154+
while (!stack.empty()) {
155+
const auto u = stack.back();
156+
stack.pop_back();
157+
order.push_back(u);
158+
for (auto ei = graph.head[static_cast<size_t>(u)]; ei != -1; ei = graph.edges[static_cast<size_t>(ei)].next) {
159+
const auto &edge = graph.edges[static_cast<size_t>(ei)];
160+
if (edge.to == parent[static_cast<size_t>(u)]) continue;
161+
parent[static_cast<size_t>(edge.to)] = u;
162+
stack.push_back(edge.to);
163+
}
164+
}
165+
std::vector<i64> dp(static_cast<size_t>(n + 1), 0);
166+
int32_t formed = 0;
167+
std::vector<i64> lengths;
168+
std::vector<bool> used;
169+
170+
for (auto it = order.rbegin(); it != order.rend(); ++it) {
171+
const auto u = *it;
172+
lengths.clear();
173+
for (auto ei = graph.head[static_cast<size_t>(u)]; ei != -1; ei = graph.edges[static_cast<size_t>(ei)].next) {
174+
const auto &edge = graph.edges[static_cast<size_t>(ei)];
175+
if (parent[static_cast<size_t>(u)] == edge.to) continue;
176+
lengths.push_back(dp[static_cast<size_t>(edge.to)] + edge.weight);
177+
}
178+
179+
std::sort(lengths.rbegin(), lengths.rend());
180+
181+
used.assign(lengths.size(), false);
182+
int32_t l = 0;
183+
int32_t r = static_cast<int32_t>(lengths.size()) - 1;
184+
185+
while (l < r) {
186+
if (used[l]) {
187+
l++;
188+
continue;
189+
}
190+
while (l < r && (used[r] || lengths[l] + lengths[r] < limit)) {
191+
r--;
192+
}
193+
if (l < r) {
194+
formed++;
195+
used[l] = used[r] = true;
196+
l++;
197+
r--;
198+
}
199+
}
200+
201+
i64 carry = 0;
202+
for(size_t i = 0; i < lengths.size(); ++i) {
203+
if (!used[i]) {
204+
if (lengths[i] >= limit) {
205+
formed++;
206+
used[i] = true;
207+
} else {
208+
carry = std::max(carry, lengths[i]);
209+
}
210+
}
211+
}
212+
dp[static_cast<size_t>(u)] = carry;
213+
}
214+
return formed >= in.m;
215+
}
216+
124217
static const auto faster_streams = [] {
125218
srand(time(nullptr));
126219
// use time to init the random seed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
4 1
2+
1 2 2
3+
2 3 3
4+
3 4 4
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
9
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
4 2
2+
1 2 7
3+
1 3 5
4+
1 4 6
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
6
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
5 2
2+
1 2 4
3+
2 3 6
4+
3 4 8
5+
3 5 3
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
10
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
6 2
2+
1 2 5
3+
1 3 3
4+
1 4 4
5+
2 5 6
6+
5 6 7
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
7

0 commit comments

Comments
 (0)