这一题k有1000000的数量级,所以我没敢开一百万的局部数组。
为什么全局有可能会出问题?因为在递归的时候,这一层的数据有可能被下一层利用。
避免的方法就是把处理和递归分开。完事!
看代码:
#include<bits/stdc++.h> using namespace std; const int maxn=1000000+100; #define inf 1e9 int n,k; int beg[maxn],nex[maxn],to[maxn],w[maxn],e; void add(int x,int y,int z){ e++;nex[e]=beg[x]; beg[x]=e;to[e]=y;w[e]=z; } int mx,rt,size; int sz[maxn],son[maxn],vis[maxn]; inline void getrt(int x,int fa){ sz[x]=1,son[x]=0; for(int i=beg[x];i;i=nex[i]){ int t=to[i]; if(t==fa||vis[t])continue; getrt(t,x); sz[x]+=sz[t]; if(son[x]<sz[t])son[x]=sz[t]; } if(son[x]<size-sz[x])son[x]=size-sz[x]; if(son[x]<mx)mx=son[x],rt=x; } int bot[maxn],top,q1[maxn],q2[maxn],ans; inline void stk(int x,int fa,int val,int edge){ if(val>k)return; if(val==k){ ans=min(ans,edge); return; } if(edge>=ans)return; q1[++top]=val; q2[top]=edge; for(int i=beg[x];i;i=nex[i]){ int t=to[i]; if(t==fa||vis[t])continue; stk(t,x,val+w[i],edge+1); } } int tmp[maxn],qwq; inline void divide(int x){ vis[x]=1;qwq=0; for(int i=beg[x];i;i=nex[i]){ int t=to[i]; if(vis[t])continue; top=0; stk(t,x,w[i],1); for(int j=1;j<=top;j++) ans=min(ans,q2[j]+bot[k-q1[j]]); for(int j=1;j<=top;j++) bot[q1[j]]=min(bot[q1[j]],q2[j]); for(int j=1;j<=top;j++) tmp[++qwq]=q1[j]; } for(int i=1;i<=qwq;i++) bot[tmp[i]]=inf; for(int i=beg[x];i;i=nex[i]){ int t=to[i]; if(vis[t])continue; mx=inf,rt=0,size=sz[t]; getrt(t,x); divide(rt); } } int main(){ cin>>n>>k; int x,y,z; for(int i=1;i<n;i++){ scanf("%d%d%d",&x,&y,&z); x++,y++; add(x,y,z),add(y,x,z); } for(int i=1;i<=k;i++) bot[i]=1e9; ans=inf; mx=inf,rt=0,size=n; getrt(1,0); divide(rt); if(ans>=n)puts("-1"); else printf("%d\n",ans); return 0; }
不巧,我又是一遍AC的,哈哈哈!