zoukankan      html  css  js  c++  java
  • 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);
    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("
    "); */
    33     printf("%d %d
    ",L,R);
    34     for(int i=1;i<=N;i++)
    35         printf("%d %d %d
    ",vs[i].u,vs[i].v,vs[i].w);
    36     return 0;
    37 }
    View Code

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

  • 相关阅读:
    PostgreSQL数据库中的常见错误
    postgresql相关命令
    Linux系统查看公网IP地址
    TCP/IP TIME_WAIT状态原理
    TCP连接状态详解及TIME_WAIT过多的解决方法
    让你提升命令行效率的 Bash 快捷键 [完整版]
    linux 如何显示一个文件的某几行(中间几行)
    linux中内核的一个不错的参数somaxconn
    Linux crontab 实现每秒执行
    Linux tar This does not look like a tar archive
  • 原文地址:https://www.cnblogs.com/wcz112/p/6430957.html
Copyright © 2011-2022 走看看