# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
431480 | Bill_00 | Race (IOI11_race) | C++14 | 0 ms | 0 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "race.h"
#include <bits/stdc++.h>
#define ff first
#define ss second
typedef long long ll;
using namespace std;
vector<pair<ll,ll> >adj[300000];
long long desired;
long long ans=1e9;
struct dp{
long long val1;
unordered_map<long long,pair<long long,bool> >um;
long long val;
vector<long long>dp;
};
dp tree[300000];
ll sz[300000];
void dfs(ll node,ll par=-1){
sz[node]=1;
for(pair<ll,ll>child:adj[node]){
if(child.first!=par){
dfs(child.first,node);
sz[node]+=sz[child.first];
}
}
}
void solve(ll node,ll par=-1){
ll dis=0;
pair<ll,ll>temp,bigchild={0,-1};
for(pair<ll,ll>child:adj[node]){
if(child.ff==par) continue;
temp={sz[child.ff],child.ff};
if(temp>bigchild){
dis=child.ss;
bigchild=temp;
}
}
if(bigchild.ss!=-1){
solve(bigchild.ss,node);
swap(tree[node],tree[bigchild.ss]);
}
tree[node].dp.push_back(-dis-tree[node].val);
tree[node].val+=dis;
tree[node].val1++;
tree[node].um[-tree[node].val].first=-tree[node].val1;
tree[node].um[-tree[node].val].second=1;
if(tree[node].um[desired-tree[node].val].ss==1){
ans=min(ans,tree[node].um[desired-tree[node].val].first+tree[node].val1);
}
for(pair<ll,ll>child:adj[node]){
if(child.ff==par) continue;
if(child.ff!=bigchild.ss){
long long dist=child.second;
solve(child.ff,node);
for(ll i=0;i<tree[child.ff].dp.size();i++){
long long actual=tree[child.ff].dp[i]+tree[child.ff].val;
long long dis1=tree[child.ff].um[tree[child.ff].dp[i]].first+tree[child.ff].val1;
bool flag=tree[node].um[desired-actual-dist-tree[node].val].second;
long long dis2=tree[node].um[desired-actual-dist-tree[node].val].first+tree[node].val1;
if(flag==1){
ans=min(ans,dis1+dis2+1);
}
actual+=dist;
actual-=tree[node].val;
if(tree[node].um[actual].ss==1){
tree[node].um[actual].ff=min(tree[node].um[actual].ff,dis1+1-tree[node].val1);
}
else{
tree[node].dp.push_back(actual);
tree[node].um[actual].ff=dis1+1-tree[node].val1;
tree[node].um[actual].ss=1;
}
}
}
}
// cout << tree[node].val << ' ' << node << '\n';
// for(int i=0;i<tree[node].dp.size();i++){
// cout << tree[node].dp[i] << ' ';
// }
// cout << '\n';
}
int best_path(int N, int K, int H[][2], int L[])
{
desired=K;
for(ll i=0;i<(N-1);i++){
adj[(ll)H[i][0]].push_back({(ll)H[i][1],(ll)L[i]});
adj[(ll)H[i][1]].push_back({(ll)H[i][0],(ll)L[i]});
}
dfs((ll)0);
solve((ll)0);
int answer=ans;
return (1000000000==answer?-1:answer);
}
int main(){
int N,K,path[200][2],L[200];
cin >> N >> K;
for(int i=0;i<(N-1);i++){
cin >> path[i][0] >> path[i][1] >> L[i];
}
cout << best_path(N,K,path,L);
}