P5021 賽道修建
阿新 • • 發佈:2020-10-14
先放一下程式碼。題解日後再補。
//80分部分分 正解還不會 #include<bits/stdc++.h> using namespace std; typedef pair<int,int> pii; #define forg(i,x) for(int i=first[x];i;i=nxt[i]) #define uu unsigned #define fi first #define se second #define od(x) ((x)&1) #define ev(x) (od(x)^1) #define mi2(x) (1<<(x)) #define scanf a1234=scanf #define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout) int a1234; char buf[1<<18],*bufs=buf,*buft=buf; inline int gc(){ return bufs==buft&&(buft=(bufs=buf)+fread(buf,1,1<<18,stdin)),bufs==buft?-1:*bufs++; } inline void xxx(){for(;;);} const int mxn=5e4+3; int n,m,to[mxn<<1],nxt[mxn<<1],first[mxn],tot=1,deg[mxn],W[mxn<<1],len[mxn],rt; inline int rd(int l,int r){return rand()%(r-l+1)+l;} inline void gadd(int x,int y,int l){to[++tot]=y,nxt[tot]=first[x],first[x]=tot,W[tot]=l,++deg[x];} struct duru{ int x,y,l; }du[mxn]; inline void dfs1(int x,int f){ forg(i,x)if(to[i]!=f)dfs1(to[i],x),len[x]=max(len[x],W[i]+len[to[i]]); } namespace task1{ int len[mxn],ans=0; inline void dfs(int x,int f){ forg(i,x)if(to[i]!=f)dfs(to[i],x),ans=max(ans,len[x]+len[to[i]]+W[i]),len[x]=max(len[x],W[i]+len[to[i]]); } int main1(){ dfs(rt,0);printf("%d\n",ans); return 0; } } int rh[mxn],nn=0; inline void getrt(){ for(int i=1;i<=n;++i)if(deg[i]<=2)rh[++nn]=i; rt=rh[rd(1,nn)]; } namespace task2{ inline bool is(){for(int i=1;i<n;++i)if(du[i].y!=du[i].x+1)return 0;return 1;} int w[mxn]; inline bool can(int x){ int cnt=0,sum=0; for(int i=1;i<n;++i){ sum+=w[i]; if(sum>=x)sum=0,++cnt; } return cnt>=m; } int main1(){ for(int i=1;i<n;++i)w[du[i].x]=du[i].l; int l=1,r=5e8+11,mid; while(l!=r){ mid=(l+r+1)>>1; if(can(mid))l=mid;else r=mid-1; } printf("%d\n",l); return 0; } } namespace task3{ inline bool is(){for(int i=1;i<n;++i)if(du[i].x!=1)return 0;return 1;} int w[mxn]; inline bool can(int x){ int nn=n,cnt=0; for(--nn;nn&&w[nn]>=x;--nn)++cnt; if(nn==0)return 1; int l=1,r=nn; while(l<r){ if(w[l]+w[r]>=x)++cnt,++l,--r;else ++l; } return cnt>=m; } int main1(){ for(int i=1;i<n;++i)w[i]=du[i].l; sort(w+1,w+n); int l=1,r=5e8+11,mid; while(l!=r){ mid=(l+r+1)>>1; if(can(mid))l=mid;else r=mid-1; } printf("%d\n",l); return 0; } } namespace task4{ inline bool is(){for(int i=1;i<=n;++i)if(deg[i]>3)return 0;return n<=1000;} const int mxn=1003; int dp[mxn][2],ls[mxn],rs[mxn],fa[mxn],w[mxn][2],ww[mxn]; int wan; inline void dfs1(int x,int f,int e){ fa[x]=f,ww[x]=W[e]; forg(i,x)if(to[i]!=f){ dfs1(to[i],x,i); if(!ls[x])ls[x]=to[i],w[x][0]=W[i];else rs[x]=to[i],w[x][1]=W[i]; } } inline void soul(int &f,int x,int sum,int up){ if(len[x]+sum<wan)return; if(sum>=wan)return f=max(f,1+up+dp[x][0]),void(); if(ls[x])soul(f,ls[x],sum+w[x][0],up+dp[rs[x]][1]); if(rs[x])soul(f,rs[x],sum+w[x][1],up+dp[ls[x]][1]); } inline void sou1(int &f,int x1,int x2,int sum,int up,bool tg){ if(sum>=wan)return f=max(f,1+up+dp[x2][0]+dp[x1][0]),void(); if(tg){ if(sum+len[x2]<wan)return; if(ls[x2])sou1(f,x1,ls[x2],sum+w[x2][0],up+dp[rs[x2]][1],1); if(rs[x2])sou1(f,x1,rs[x2],sum+w[x2][1],up+dp[ls[x2]][1],1); }else{ if(sum+len[x1]+len[x2]<wan)return; sou1(f,x1,x2,sum,up,1); if(ls[x1])sou1(f,ls[x1],x2,sum+w[x1][0],up+dp[rs[x1]][1],0); if(rs[x1])sou1(f,rs[x1],x2,sum+w[x1][1],up+dp[ls[x1]][1],0); } } inline void dfs(int x){ if(ls[x])dfs(ls[x]);if(rs[x])dfs(rs[x]); dp[x][0]=max(dp[ls[x]][0]+dp[rs[x]][1],dp[rs[x]][0]+dp[ls[x]][1]); soul(dp[x][0],x,0,0); if(ls[x]&&rs[x])sou1(dp[x][0],ls[x],rs[x],w[x][0]+w[x][1],0,0); if(x==rt||ww[x]>=wan)return dp[x][1]=dp[x][0]+1,void(); dp[x][1]=dp[x][0]; soul(dp[x][1],x,ww[x],0); } inline bool can(){ memset(dp,0,sizeof(dp)); dfs(rt); return dp[rt][0]>=m; } int main1(){ // puts("OKKKKKKKKKKKKKKKKK"); dfs1(rt,0,0); int l=1,r=n*10000; while(l<r){ wan=(l+r+1)>>1; if(can())l=wan;else r=wan-1; } printf("%d\n",l); return 0; } } int main(){ srand((uu)time(0)); scanf("%d%d",&n,&m);for(int i=1,u,v,l;i<n;++i)scanf("%d%d%d",&u,&v,&l),du[i]=(duru){u,v,l},gadd(u,v,l),gadd(v,u,l); getrt(); dfs1(rt,0); if(task4::is())return task4::main1(); // puts("ohwwwwwwwwwww"); if(m==1)return task1::main1(); if(task2::is())return task2::main1(); if(task3::is())return task3::main1(); return 0; }
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> pii; #define forg(i,x) for(int i=first[x];i;i=nxt[i]) #define uu unsigned #define fi first #define se second #define od(x) ((x)&1) #define ev(x) (od(x)^1) #define mi2(x) (1<<(x)) #define scanf a1234=scanf #define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout) #define fp fprintf int a1234; char buf[1<<18],*bufs=buf,*buft=buf; inline int gc(){ return bufs==buft&&(buft=(bufs=buf)+fread(buf,1,1<<18,stdin)),bufs==buft?-1:*bufs++; } inline void xxx(){for(;;);} inline int rd(int l,int r){return rand()%(r-l+1)+l;} FILE*fo; int tmp[1003]; inline void dfs(int l,int r){ if(l==r)return; int lc=rd(1,r-l); if(lc==r-l)return fp(fo,"%d %d %d\n",tmp[l],tmp[l+1],rd(1,10000)),dfs(l+1,r); dfs(l+1,l+lc),dfs(l+lc+1,r); fp(fo,"%d %d %d\n",tmp[l],tmp[l+1],rd(1,10000)),fp(fo,"%d %d %d\n",tmp[l],tmp[l+lc+1],rd(1,10000)); } inline void maked(){ fo=fopen("te.in","w"); int n=1000,m=rd(1,n-1); for(int i=1;i<=n;++i)tmp[i]=i;random_shuffle(tmp+1,tmp+n+1); fp(fo,"%d %d\n",n,m); dfs(1,n); fclose(fo); } inline uu work(){ maked(); system("./a<te.in>1.ans"),system("./b<te.in>2.ans"); return system("diff 1.ans 2.ans -b -B -q"); } int main(){ srand((uu)time(0)); //return maked(),3; system("g++ a.cpp -O2 -Wall -o a"),system("g++ b.cpp -O2 -Wall -o b"); int cases=0; while(1){printf("%d\n",++cases);if(work())return 222;if(cases==1000)return 0;} return 0; }