【比賽】NOIP2018 賽道修建
阿新 • • 發佈:2019-01-01
最小值最大,二分長度
然後判斷賽道大於等於這個長度最多可以有多少條
可以貪心,對於一個點和它的一些兒子,兒子與兒子之間儘量多配(排序後一大一小),剩下的選個最長的留給自己的父親就好了
具體實現可以用一個set(自測會被卡常,但是少爺機似乎很快)
#include<bits/stdc++.h> #define ui unsigned int #define ll long long #define db double #define ld long double #define ull unsigned long long #define ft first #define sd second #define pb(a) push_back(a) #define mp(a,b) std::make_pair(a,b) #define REP(a,b,c) for(register int a=(b),a##end=(c);a<=a##end;++a) #define DEP(a,b,c) for(register int a=(b),a##end=(c);a>=a##end;--a) const int MAXN=50000+10; int n,m,e,beg[MAXN],nex[MAXN<<1],to[MAXN<<1],was[MAXN<<1],cnt,now[MAXN],lcnt,val[MAXN]; std::multiset<int> S; std::multiset<int>::iterator it,nit; template<typename T> inline void read(T &x) { T data=0,w=1; char ch=0; while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); if(ch=='-')w=-1,ch=getchar(); while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar(); x=data*w; } template<typename T> inline void write(T x,char ch='\0') { if(x<0)putchar('-'),x=-x; if(x>9)write(x/10); putchar(x%10+'0'); if(ch!='\0')putchar(ch); } template<typename T> inline bool chkmin(T &x,T y){return y<x?(x=y,true):false;} template<typename T> inline bool chkmax(T &x,T y){return y>x?(x=y,true):false;} template<typename T> inline T min(T x,T y){return x<y?x:y;} template<typename T> inline T max(T x,T y){return x>y?x:y;} inline void insert(int x,int y,int z) { to[++e]=y; nex[e]=beg[x]; beg[x]=e; was[e]=z; } inline void dfs(int x,int f,int len) { for(register int i=beg[x];i;i=nex[i]) if(to[i]==f)continue; else dfs(to[i],x,len); for(register int i=beg[x];i;i=nex[i]) if(to[i]==f)continue; else S.insert(val[to[i]]+was[i]); if(S.empty())return ; it=S.end();it--; while((*it)>=len) { S.erase(it);cnt++; if(S.empty())break; it=S.end(),it--; } int las=0; if(S.empty())return ; it=S.begin(); while(it!=S.end()) { nit=S.lower_bound(len-(*it)); if(nit==S.end())chkmax(las,*it),S.erase(it); else if(it==nit) { nit++; if(nit==S.end())chkmax(las,*it),S.erase(it); else S.erase(it),S.erase(nit),cnt++; } else S.erase(it),S.erase(nit),cnt++; it=S.begin(); } val[x]=las; } inline bool check(int len) { REP(i,1,n)val[i]=0; cnt=0,dfs(1,0,len); return cnt>=m; } int main() { freopen("track.in","r",stdin); freopen("track.out","w",stdout); read(n);read(m); REP(i,1,n-1) { int u,v,w;read(u);read(v);read(w); insert(u,v,w);insert(v,u,w); } int l=1,r=5e8,ans=1; while(l<=r) { int mid=(l+r)>>1; if(check(mid))ans=mid,l=mid+1; else r=mid-1; } write(ans,'\n'); return 0; }