您的位置:首页 > 其它

wc2010 bzoj1758(点分治+二分+单调队列) TLE

2016-12-18 00:17 399 查看
 本机测试没有问题,提交tle

 

 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;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: