# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
881016 | minhi1 | 경주 (Race) (IOI11_race) | C++14 | 0 ms | 0 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 6;
int n, res = (int)1e9;
long long target;
int sz[N];
int mp[N];
bool is_removed[N];
bool in_map[N];
vector < int > del;
vector < pair < int , int > > adj[N];
int dfs_sz(int u, int p = -1) {
sz[u] = 1;
for (auto [v, w] : adj[u]) {
if (v == p || is_removed[v]) continue;
sz[u] += dfs_sz(v, u);
}
return sz[u];
}
int get_cent(int u, int tree_size, int p) {
for (auto [v, w] : adj[u]) {
if (v == p || is_removed[v]) continue;
if (sz[v] * 2 > tree_size) return get_cent(v, tree_size, u);
}
return u;
}
void solve(int u, int cent, int p, long long sum, int dist) {
if (sum <= target && mp[target - sum] > 0)
res = min(res, dist + mp[target - sum]);
if (sum == target) res = min(res, dist);
for (auto [v, w] : adj[u]) {
if (v == p || is_removed[v]) continue;
if (sum + w > target) continue;
solve(v, cent, u, sum + w, dist + 1);
}
}
void upd(int u, int cent, int p, long long sum, int dist) {
if (sum <= target) {
int val = mp[sum];
val = (val == 0 ? dist : min(val, dist));
mp[sum] = val;
if (!in_map[sum]) {
in_map[sum] = true;
del.push_back(sum);
}
}
for (auto [v, w] : adj[u]) {
if (v == p || is_removed[v]) continue;
if (sum + w > target) continue;
upd(v, cent, u, sum + w, dist + 1);
}
}
void decomp(int u) {
int cent = get_cent(u, dfs_sz(u), -1);
for (auto [v, w] : adj[cent]) {
if (is_removed[v]) continue;
solve(v, cent, cent, w, 1);
upd(v, cent, cent, w, 1);
}
// TODO: refresh
for (int sum : del) {
mp[sum] = 0;
in_map[sum] = 0;
}
del.clear();
is_removed[cent] = true;
for (auto [v, w] : adj[cent]) {
if (is_removed[v]) continue;
decomp(v);
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
#ifdef trcute
freopen("test.inp", "r", stdin);
// freopen("test.out", "w", stdout);
#endif
cin >> n >> target;
for (int i = 1; i < n; ++i) {
int u, v, w;
cin >> u >> v >> w;
++u; ++v;
adj[u].push_back({v, w});
adj[v].push_back({u, w});
}
decomp(1);
cout << (res == (int)1e9 ? -1 : res);
return 0;
}