wc2010 bzoj1758(点分治+二分+单调队列) TLE
2016-12-18 00:17
399 查看
本机测试没有问题,提交tle
updata 2017 4 2 tle ing
updata 2017 4 2 tle ing
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<cstdlib> #include<queue> using namespace std; const int N=100005; inline int read() { int ans;char ch; while ((ch=getchar())<'0'||ch>'9') ;ans=ch-'0'; while ((ch=getchar())>='0'&&ch<='9') ans=ans*10+ch-'0'; return ans; } int n,L,R; int head ,tot; struct aa { int to,pre;double dis; }edge[N*2]; void addedge(int u,int v,double d) { edge[++tot].to=v;edge[tot].pre=head[u];edge[tot].dis=d;head[u]=tot; } bool vis ,b ; int size ,sum,mi,rt; void get_size(int u,int fa) { size[u]=1; for (int i=head[u];i;i=edge[i].pre) if (!vis[edge[i].to]&&edge[i].to!=fa) { get_size(edge[i].to,u); size[u]+=size[edge[i].to]; } } void get_rt(int u,int fa) { int mx=sum-size[u]; for (int i=head[u];i;i=edge[i].pre) if (!vis[edge[i].to]&&edge[i].to!=fa) { get_rt(edge[i].to,u); mx=max(mx,size[edge[i].to]); } if (mx<mi) mi=mx,rt=u; } /////////////////////// int dep ;double dis ,MX=0,ans=1e9; int q ,hd,tl; void bfs(double mid) { while (hd<=tl) { if (dep[hd]==R) break; for (int v,i=head[q[hd]];i;i=edge[i].pre) if (!vis[v=edge[i].to]&&!b[v]) { b[v]=true; q[++tl]=v; dep[tl]=dep[hd]+1; dis[tl]=dis[hd]+edge[i].dis-mid; } hd++; } } int ll,rr,id ,begin,end; double f ,s ; bool pan(int rt,double mid) { double ans=-1e9; int mx=0; for (int i=1;i<=size[rt];i++) f[i]=-1e9;f[0]=0; for (int u,i=head[rt];i;i=edge[i].pre) if (!vis[u=edge[i].to]) { q[hd=tl=1]=u; dep[hd]=1,dis[hd]=edge[i].dis-mid;b[u]=true; bfs(mid); ll=rr=min(mx,R+1); s[begin=end=1]=f[rr],id[begin]=rr; for (int j=1;j<=tl;j++) { if (dep[j]+ll<L) continue; while (dep[j]+ll>L&&ll>0) { ll--; while (f[ll]>s[end]&&begin<=end) end--; s[++end]=f[ll];id[end]=ll; } while (dep[j]+rr>R) rr--; while (id[begin]>rr) begin++; ans=max(ans,s[begin]+dis[j]); } for (int j=1;j<=tl;j++) f[dep[j]]=max(f[dep[j]],dis[j]),b[q[j]]=false; mx=max(mx,size[u]); } return ans>0; } void work(int u) { double mid,l=ans,r=MX; while (l+0.0002<r) { mid=(l*3+r)/4; if (pan(u,mid)) l=mid;else r=mid; } ans=l; } /////////////////////// void dfs(int u) { get_size(u,0);sum=size[u];mi=1e9; get_rt(u,0);u=rt; if (sum<=L) return ; vis[u]=true; work(u); for (int i=head[u];i;i=edge[i].pre) if (!vis[edge[i].to]) dfs(edge[i].to); } int main() { n=read(),L=read(),R=read(); int u,v,d; for (int i=1;i<n;i++) { u=read(),v=read(),d=read(); addedge(u,v,d); addedge(v,u,d); MX=max(MX,double(d)); ans=min(ans,double(d)); } dfs(1); printf("%.3lf",ans); return 0; }
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #include<queue> using namespace std; const int inf=0x3f3f3f3f; const int N=1000005; int n,L,U; double ans; int size ,sum,mi,rt; bool vis ,b ; int head ,tot; struct aa { int to,pre,dis; }edge[N*2]; void addedge(int u,int v,int d) { edge[++tot].to=v;edge[tot].pre=head[u];edge[tot].dis=d;head[u]=tot; } void get_size(int u,int fa) { size[u]=1;b[u]=false; for (int i=head[u];i;i=edge[i].pre) if (!vis[edge[i].to]&&edge[i].to!=fa) { get_size(edge[i].to,u); size[u]+=size[edge[i].to]; } } void get_rt(int u,int fa) { int mx=sum-size[u]; for (int i=head[u];i;i=edge[i].pre) if (!vis[edge[i].to]&&edge[i].to!=fa) { get_rt(edge[i].to,u); mx=max(mx,size[edge[i].to]); } if (mx<mi) mi=mx,rt=u; } double f ,g ; int q ,tail,yy ; void bfs(int u,double d,double jian) { int hd=1;tail=0; q[++tail]=u;yy[tail]=1,g[tail]=d;b[u]=true; while (hd<=tail) { int v=q[hd]; for (int i=head[v];i;i=edge[i].pre) if (!vis[edge[i].to]&&!b[edge[i].to]) { b[edge[i].to]=true; q[++tail]=edge[i].to; yy[tail]=yy[hd]+1; g[tail]=g[hd]+(double)edge[i].dis-jian; } hd++; } } int q0 ,tl,hd; double q1 ; void push(int i) { while (hd<=tl&&f[i]>q1[tl]) tl--; q0[++tl]=i,q1[tl]=f[i]; } bool pan(double jian,int u) { int mx=0; for (int ii=head[u];ii;ii=edge[ii].pre) if (!vis[edge[ii].to]) { int v=edge[ii].to; bfs(v,(double)edge[ii].dis-jian,jian); hd=1,tl=1;q0[tl]=mx,q1[tl]=f[mx]; for (int i=1;i<=tail;i++) { int d=yy[i];double dis=g[i]; int ll=max(L-d,0),rr=U-d; if (ll>mx) continue; if (rr<0) break; while (ll<q0[tl]) push(q0[tl]-1); while (rr<q0[hd]&&hd<=tl) hd++; if (g[i]+q1[hd]>=0) { for (int j=1;j<=mx;j++) f[j]=-1e11; for (int j=1;j<=tail;j++) b[q[j]]=false; return true; } } mx=max(mx,yy[tail]); mx=min(mx,U); for (int i=1;i<=tail;i++) { int d=yy[i];double dis=g[i];b[q[i]]=false; if (d>U) continue; f[d]=max(f[d],dis); } } for (int i=1;i<=mx;i++) f[i]=-1e11; return false; } int lim; void work(int u) { double l=0,r=lim,mid; while (l+0.0001<r) { mid=(l+r)/2; if (pan(mid,u)) l=mid; else r=mid; } // printf("%lf\n",l); if (l>ans) ans=l; } void dfs(int u) { get_size(u,0);sum=size[u];mi=inf; get_rt(u,0);u=rt; if (sum<=L) return ; vis[u]=true; work(u); for (int i=head[u];i;i=edge[i].pre) if (!vis[edge[i].to]) dfs(edge[i].to); } inline int read() { int ans,f=1;char ch; while ((ch=getchar())<'0'||ch>'9') if (ch=='-') f=-1;ans=ch-'0'; while ((ch=getchar())>='0'&&ch<='9') ans=ans*10+ch-'0'; return ans*f; } int main() { n=read();L=read();U=read(); int x,y,z; for (int i=1;i<n;i++) { x=read();y=read();z=read(); addedge(x,y,z); addedge(y,x,z); lim=max(lim,z); } for (int i=1;i<=U;i++) f[i]=-1e11; dfs(1); printf("%.3f",ans); return 0; }
相关文章推荐
- BZOJ1758 [Wc2010]重建计划(二分答案+点分治+单调队列)
- 【bzoj1758】[Wc2010]重建计划 二分答案+单调队列+点分治
- BZOJ 1758 Wc2010 重建计划 树的点分治+二分+单调队列
- bzoj 1758 [Wc2010]重建计划 01分数规划 点分治 单调队列
- 【BZOJ1758】【Wc2010】重建计划 分数规划+树分治单调队列check
- 【BZOJ】【P1758】【Wc2010】【重建计划】【题解】【点分治+二分+单调队列】
- 【BZOJ1758】【WC2010】重建计划(点分治,单调队列)
- BZOJ1758: [Wc2010]重建计划(01分数规划+点分治+单调队列)
- 【BZOJ 1758】【WC 2010】重建计划 分数规划+点分治+单调队列
- bzoj1758 [Wc2010]重建计划(二分答案+点分治+单调栈)
- 【BZOJ1758】【Wc2010】重建计划 树的点分治 二分
- BZOJ1758【点分治】【二分】【单调队列】
- 【BZOJ】【P2096】【Poi2010】【Pilots】【题解】【二分+单调队列】
- bzoj 1758: [Wc2010]重建计划 (01分数规划+点分治)
- bzoj1758 [Wc2010]重建计划(点分治+01分数规划)
- 【BZOJ1758】重建计划,点分治+单调队列
- Bzoj:1758:[Wc2010]重建计划:树的点分治
- 树的点分治 bzoj1758【WC2010】重建计划
- bzoj 3219: 巡游 (点分治+单调队列+二分)
- bzoj3219 巡游(二分答案+点分治+单调队列)