#include using namespace std; ///--------------------------------------------------- const int BUFFER_SIZE = (1 << 20); char buffer[BUFFER_SIZE]; int position = BUFFER_SIZE; inline char getChar() { if ( position == BUFFER_SIZE ) { position = 0; fread(buffer, BUFFER_SIZE, 1, stdin); } return buffer[position++]; } template inline T getInt() { register T a = 0; char ch; int sgn = 1; do { ch = getChar(); } while ( !isdigit(ch) && ch != '-' ); if ( ch == '-' ) { sgn = -1; ch = getChar(); } do { a = (a << 3) + (a << 1) + ch - '0'; ch = getChar(); } while ( isdigit(ch) ); return a * sgn; } ///--------------------------------------------------- const int MAX_N = 100000 + 5; const int NIL = -1; struct Edge { int nod; int weight; int urm; }; int head[MAX_N]; Edge G[2 * MAX_N]; int sizeTree[MAX_N]; int N; long long K; int contor = 0; void addEdge(int x, int y, int w) { G[contor] = {y, w, head[x]}; head[x] = contor++; } void dfs(int node, int parent) { sizeTree[node] = 1; for (int p = head[node]; p != NIL; p = G[p].urm) { int v = G[p].nod; if (v != parent) { dfs(v, node); sizeTree[node] += sizeTree[v]; } } } struct Node { int lazy; priority_queue MaxHeap; }; Node tree[MAX_N]; int whichHeap[MAX_N]; void lazy_delete(priority_queue &heap, int lazy, int cost) { while (heap.size() && heap.top() + lazy > cost) heap.pop(); } void dfsCount(int node, int parent, long long &numbPaths, const int cost) { if (sizeTree[node] == 1) { whichHeap[node] = node; tree[ whichHeap[node] ].lazy = 0; tree[ whichHeap[node] ].MaxHeap.push(0); return; } for (int p = head[node]; p != NIL; p = G[p].urm) { int v = G[p].nod; if (v != parent) dfsCount(v, node, numbPaths, cost); } int heavySon = 0; int heavyEdge = 0; for (int p = head[node]; p != NIL; p = G[p].urm) { int v = G[p].nod; int w = G[p].weight; if (v != parent) { if (sizeTree[v] > sizeTree[heavySon]) { heavySon = v; heavyEdge = w; } } } for (int p = head[node]; p != NIL; p = G[p].urm) { int v = G[p].nod; int w = G[p].weight; if (v != parent) { if (v != heavySon) { while (tree[ whichHeap[v] ].MaxHeap.size()) { int e = tree[ whichHeap[v] ].MaxHeap.top(); e += tree[ whichHeap[v] ].lazy; e += static_cast(w); e -= static_cast(heavyEdge + tree[ whichHeap[heavySon] ].lazy); tree[ whichHeap[heavySon] ].MaxHeap.push(e); tree[ whichHeap[v] ].MaxHeap.pop(); } tree[ whichHeap[v] ].lazy = 0; } } } whichHeap[node] = whichHeap[heavySon]; tree[ whichHeap[node] ].lazy += heavyEdge; lazy_delete(tree[ whichHeap[node] ].MaxHeap, tree[ whichHeap[node] ].lazy, cost); numbPaths += static_cast(tree[ whichHeap[node] ].MaxHeap.size()); tree[ whichHeap[node] ].MaxHeap.push(-tree[ whichHeap[node] ].lazy); } long long countPaths(int cost) { for (int i = 1; i <= N; ++i) { whichHeap[i] = 0; tree[i].lazy = 0; while (tree[i].MaxHeap.size()) tree[i].MaxHeap.pop(); } long long numbPaths = 0; dfsCount(1, 0, numbPaths, cost); return numbPaths; } int main() { ///freopen("data.in", "r", stdin); contor = 0; N = getInt(); K = getInt(); for (int i = 1; i <= N; ++i) head[i] = NIL; for (int i = 1; i < N; ++i) { int a = getInt(); int b = getInt(); int c = getInt(); addEdge(a, b, c); addEdge(b, a, c); } dfs(1, 0); ///solve -1 case long long numbPaths = 0; for (int i = 1; i <= N; ++i) numbPaths += static_cast(sizeTree[i] - 1); if (numbPaths < K) cout << "-1\n"; else { int l = 0, r = numeric_limits::max() / 2; int found = -1; while (l <= r) { int m = (l + r) / 2; if (countPaths(m) >= K) { found = m; r = m - 1; } else l = m + 1; } assert(found != -1); cout << found << "\n"; } return 0; }