1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
| #include <queue>
#include <stack>
#include <cstdio>
#include <algorithm>
const int MAXN = 200001, MAXK = 2000001;
typedef std::pair<int, int> Pair;
struct Edge
{
int v, w;
Edge *next;
} g[MAXN*2], *header[MAXN];
void AddEdge(const int x, const int y, const int w)
{
static int LinkSize;
Edge* const node = g+(LinkSize++);
node->v = y;
node->w = w;
node->next = header[x];
header[x] = node;
}
int n, K, parent[MAXN], ans = 0x3F3F3F3F;
bool mark[MAXN];
std::queue<int> q;
int getcore(const int root)
{
static int son[MAXN];
static std::stack<int> s;
int nodes = 0;
for (q.push(root), parent[root] = -1; !q.empty(); q.pop())
{
const int u = q.front();
s.push(u);
++nodes;
for (Edge *e = header[u]; e; e = e->next)
if (!mark[e->v] && e->v != parent[u])
{
parent[e->v] = u;
q.push(e->v);
}
}
int core = 0x3F3F3F3F, m = 0x3F3F3F3F;
for (; !s.empty(); s.pop())
{
const int u = s.top();
int maxson = 0, cnt = 0;
for (Edge *e = header[u]; e; e = e->next)
if (!mark[e->v] && e->v != parent[u])
{
cnt += son[e->v];
maxson = std::max(maxson, son[e->v]);
}
maxson = std::max(maxson, nodes-(son[u] = cnt+1));
if (maxson < m)
m = maxson, core = u;
}
return core;
}
void solve(const int core)
{
static int timestamp;
static Pair dist[MAXN], m[MAXK];
mark[core] = true;
m[0].first = 0, m[0].second = ++timestamp;
for (Edge *edge = header[core]; edge; edge = edge->next)
{
const int st = edge->v;
if (mark[st]) continue;
for (q.push(st), dist[st].first = edge->w, dist[st].second = 1, parent[st] = -1; !q.empty(); q.pop())
{
const int u = q.front();
if (dist[u].first <= K && m[K-dist[u].first].second == timestamp)
ans = std::min(ans, dist[u].second + m[K-dist[u].first].first);
for (Edge *e = header[u]; e; e = e->next)
{
if (mark[e->v] || parent[u] == e->v) continue;
parent[e->v] = u;
dist[e->v].first = dist[u].first + e->w;
dist[e->v].second = dist[u].second + 1;
q.push(e->v);
}
}
for (q.push(st); !q.empty(); q.pop())
{
const int u = q.front();
if (dist[u].first <= K && (m[dist[u].first].second != timestamp || dist[u].second < m[dist[u].first].first))
{
m[dist[u].first].first = dist[u].second;
m[dist[u].first].second = timestamp;
}
for (Edge *e = header[u]; e; e = e->next)
if (!mark[e->v] && parent[u] != e->v)
q.push(e->v);
}
}
}
int main()
{
scanf("%d%d", &n, &K);
for (int i = 1, x, y, w; i < n; ++i)
{
scanf("%d%d%d", &x, &y, &w);
AddEdge(++x, ++y, w);
AddEdge(y, x, w);
}
std::queue<int> Q;
for (Q.push(1); !Q.empty(); Q.pop())
{
const int u = Q.front();
const int core = getcore(u);
solve(core);
for (Edge *e = header[core]; e; e = e->next)
if (!mark[e->v])
Q.push(e->v);
}
printf("%d", ans == 0x3F3F3F3F ? -1 : ans);
}
|