1. 程式人生 > >解題:NOIP 2018 賽道修建

解題:NOIP 2018 賽道修建

cor pla clas 想想 div spl text scanf line

題面

幾乎把我送退役的一道題,留在這裏做個紀念。

考場看出來是原題結果為了求穩強行花了一個小時寫了80pts暴力,然後掛了55pts(真·暴力寫掛),結果今天花了不到半個小時連想帶寫一遍95pts(T一個菊花圖的點),淦,想想就氣,A了就HE rank3了(434->509)(算了反正你太菜了當時不敢寫,再打馬後炮也沒用了

然後左轉這道題(這甚至是個弱化版),做完了(懶得卡那一個點的常了,開O2了)

技術分享圖片
 1 // luogu-judger-enable-o2
 2 #include<set>
 3 #include<cstdio>
 4 #include<cstring>
 5
#include<algorithm> 6 using namespace std; 7 const int N=50005,inf=1e9; 8 int p[N],noww[2*N],goal[2*N],val[2*N],deg[N],dp[N][2]; 9 int n,m,l,r,mid,ans,t1,t2,t3,cnt; 10 multiset<int> mst; 11 multiset<int>::iterator it1,it2; 12 void link(int f,int t,int v) 13 { 14 noww[++cnt]=p[f],p[f]=cnt;
15 goal[cnt]=t,val[cnt]=v,deg[t]++; 16 } 17 void DFS(int nde,int fth) 18 { 19 if(deg[nde]==1&&nde!=1) return ; 20 for(int i=p[nde];i;i=noww[i]) 21 if(goal[i]!=fth) 22 { 23 DFS(goal[i],nde); 24 dp[nde][0]+=dp[goal[i]][0]; 25 } 26 for
(int i=p[nde];i;i=noww[i]) 27 if(goal[i]!=fth) 28 mst.insert(dp[goal[i]][1]+val[i]); 29 while(!mst.empty()&&(*mst.rbegin()>=mid)) 30 dp[nde][0]++,mst.erase(--mst.end()); 31 while(mst.size()>1) 32 { 33 it1=mst.begin(); 34 int tmp=*it1; mst.erase(it1); 35 it2=mst.lower_bound(mid-tmp); 36 if(it2!=mst.end()) 37 dp[nde][0]++,mst.erase(it2); 38 else dp[nde][1]=max(dp[nde][1],tmp); 39 } 40 if(mst.size()) dp[nde][1]=max(dp[nde][1],*mst.begin()); 41 mst.clear(); 42 } 43 bool check() 44 { 45 memset(dp,0,sizeof dp); 46 DFS(1,0); return dp[1][0]>=m; 47 } 48 int main() 49 { 50 scanf("%d%d",&n,&m); 51 for(int i=1;i<n;i++) 52 { 53 scanf("%d%d%d",&t1,&t2,&t3),r+=t3; 54 link(t1,t2,t3),link(t2,t1,t3); 55 } 56 while(l<=r) 57 { 58 mid=(l+r)/2; 59 if(check()) l=mid+1,ans=mid; 60 else r=mid-1; 61 } 62 printf("%d",ans); 63 return 0; 64 }
View Code

解題:NOIP 2018 賽道修建