BZOJ 1758

mengbing。。。。。

大家都说这是一道卡常题 、名不虚传、233333

树分治 再加上迭代答案 而不是二分 就可以过了

迭代的次数 平均下来 大概就只有 2.8次的样子 

需要单调队列优化更新答案的过程

BZOJ 1758
  1 #include <bits/stdc++.h>
  2 #define N 100010
  3 #define inf 1e10
  4 using namespace std;
  5 inline int read()
  6 {
  7     int x=0,f=1; char ch=getchar();
  8     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
  9     while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
 10     return x*f;
 11 }
 12 struct edge
 13 {
 14     int v,next,w;
 15 }vs[N<<1];
 16 int n,L,R,q[N],vis[N],sum,Rtt;
 17 int st[N],ee,Rt,size[N],tp[N],dep[N];
 18 int stk[N],top,fa[N],mxd;
 19 double prestans=0.0,ans,vopt[N],,f[N];
 20 vector <int> Gp[N];
 21 inline void addedge(int u,int v,int w)
 22 {
 23     vs[++ee].v=v;vs[ee].w=w;
 24     vs[ee].next=st[u];st[u]=ee;
 25 }
 26 void dfs1(int rt,int pr)
 27 {
 28     size[rt]=1;
 29     for(int i=st[rt];i;i=vs[i].next)
 30     {
 31         if(vs[i].v==pr||vis[vs[i].v]) continue;
 32         dfs1(vs[i].v,rt);
 33         size[rt]+=size[vs[i].v];
 34     }
 35 }
 36 void dfs2(int rt,int pr)
 37 {
 38     tp[rt]=0;
 39     for(int i=st[rt];i;i=vs[i].next)
 40     {
 41         if(vs[i].v==pr||vis[vs[i].v]) continue;
 42         dfs2(vs[i].v,rt);
 43         tp[rt]=max(tp[rt],size[vs[i].v]);
 44     }
 45     tp[rt]=max(tp[rt],sum-size[rt]);
 46     if(tp[rt]<tp[Rtt]) Rtt=rt;
 47 }
 48 void predeal(int rt)
 49 {
 50     vis[rt]=1;
 51     for(int i=st[rt];i;i=vs[i].next)
 52     {
 53         if(vis[vs[i].v]) continue;
 54         Rtt=0; dfs1(vs[i].v,rt);
 55         sum=size[vs[i].v];
 56         dfs2(vs[i].v,rt);
 57         Gp[rt].push_back(Rtt);
 58         predeal(Rtt);
 59     }
 60 }
 61 void getans(int rt,int val)
 62 {
 63     stk[top=1]=rt; fa[1]=0; f[1]=val; dep[1]=1;
 64     for(int i=1;i<=top;i++)
 65     {
 66         for(int j=st[stk[i]];j;j=vs[j].next)
 67         {
 68             if(vis[vs[j].v]||vs[j].v==fa[i]) continue;
 69             stk[++top]=vs[j].v; dep[top]=dep[i]+1;
 70             fa[top]=stk[i]; f[top]=f[i]+vs[j].w;
 71         }
 72     }
 73     int l=1,r=0,pre=mxd;
 74     for(int i=1,j;i<=top;i=j)
 75     {
 76         double mx=-inf;
 77         for(j=i;dep[j]==dep[i]&&j<=top;j++)
 78             mx=max(mx,f[j]);
 79         while(pre>=0&&pre>=L-dep[i])
 80         {
 81             while(vopt[q[r]]<vopt[pre]&&r>=l) r--;
 82             q[++r]=pre; pre--;
 83         }
 84         
 85         while(q[l]+dep[i]>R&&l<=r) l++;
 86         if(l<=r) ans=max(ans,(vopt[q[l]]+mx+prestans*q[l])/(q[l]+dep[i]));
 87     }
 88     for(int i=1;i<=top;i++)
 89         vopt[dep[i]]=max(vopt[dep[i]],f[i]-dep[i]*prestans);
 90     mxd=max(mxd,dep[top]);
 91 }
 92 void solve(int rt)
 93 {
 94     vis[rt]=1; mxd=0; vopt[0]=0;
 95     for(int i=st[rt];i;i=vs[i].next)
 96     {
 97         if(vis[vs[i].v]) continue;
 98         getans(vs[i].v,vs[i].w);
 99     }
100     for(int i=0;i<=mxd;i++) vopt[i]=-inf;
101     for(unsigned i=0;i<Gp[rt].size();i++)
102         solve(Gp[rt][i]);
103 }
104 double check()
105 {
106     memset(vis,0,sizeof vis);
107     ans=-inf;
108     solve(Rt);
109     return ans;
110 }
111 int main()
112 {
113     //freopen("read.in","r",stdin);
114     n=read();L=read();R=read();
115     for(int i=1;i<n;i++)
116     {
117         int x=read(),y=read(),w=read();
118         addedge(x,y,w);addedge(y,x,w);
119     }
120     dfs1(1,0);
121     Rtt=0; tp[0]=n+1; sum=n;
122     dfs2(1,0); 
123     Rt=Rtt; predeal(Rt);
124     for(int i=1;i<=n;i++) vopt[i]=-inf;
125         for(int i=1;i<=3;i++)
126         prestans=check();
127     printf("%.3lf",prestans);
128     return 0;
129 }
View Code

↓↓↓↓ dmk ↓↓↓↓

 1 #include <bits/stdc++.h>
 2 #define N 100000
 3 using namespace std;
 4 
 5 struct edge
 6 {
 7     int u,v,next,w;
 8 }vs[N<<1];
 9 int st[N+100],ee,dep[N+100],mx1,mx2;
10 inline void addedge(int u,int v,int w)
11 {
12     vs[++ee].v=v;vs[ee].next=st[u];
13     vs[ee].u=u;vs[ee].w=w;st[u]=ee;
14 }
15 int main()
16 {
17     srand(time(0));
18     freopen("read.in","w",stdout);
19     printf("%d\n",N);
20     for(int i=2;i<=N;i++)
21     {
22         int u=rand()*rand()%(i-1)+1;
23         addedge(u,i,rand()*rand()%1000000);
24         dep[i]=dep[u]+1;
25         if(dep[i]>=mx1) mx2=mx1,mx1=dep[i];
26         else if(dep[i]>mx2) mx2=dep[i];
27     }
28     int L=rand()*rand()%(mx1+mx2)+1,R=rand()*rand()%(mx1+mx2)+1;
29     if(L>R) swap(L,R);
30 /*     sort(dep+1,dep+1+N);
31     for(int i=1;i<=N;i++)
32         printf("%d ",dep[i]); printf("\n"); */
33     printf("%d %d\n",L,R);
34     for(int i=1;i<=N;i++)
35         printf("%d %d %d\n",vs[i].u,vs[i].v,vs[i].w);
36     return 0;
37 }
View Code

好好讲道理 应该求出直径 所以这个dmk 有问题2333 但总体还是能拍得出来 逃

posted @ 2017-02-22 21:00  蛤鸡  阅读(223)  评论(0编辑  收藏  举报