• 【bzoj1758】[Wc2010]重建计划


    Description

    Input

    第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai,Bi,Vi分别表示道路(Ai,Bi),其价值为Vi 其中城市由1..N进行标号

    Output

    输出最大平均估值,保留三位小数

    Sample Input

    4
    2 3
    1 2 1
    1 3 2
    1 4 3

    Sample Output

    2.500

    HINT

    N<=100000,1<=L<=U<=N-1,Vi<=1000000 新加数据一组 By leoly,但未重测..2016.9.27

    题解:

      好一个扫把树……长见识长见识。

      显然二分答案+树的点分治。每次遍历一棵子树来得到$dis$数组,表示同一路径数的最大权值,然后再存一个之前遍历子树的桶,含义与$dis$一样,但是要注意从小到大处理每棵子树。扫把树……卡死人。

      顺便一提,bzoj不会爆栈。

      (空行比较多,所以显得很长……)

      1 #define Troy 09/30/2017
      2  
      3 #define inf 0x7fffffff
      4  
      5 #include <bits/stdc++.h>
      6  
      7 using namespace std;
      8  
      9 typedef long long ll;
     10  
     11 const int N=500100;
     12 const double eps=1e-4;
     13  
     14 inline int read(){
     15     int s=0,k=1;char ch=getchar();
     16     while(ch<'0'|ch>'9')  ch=='-'?k=-1:0,ch=getchar();
     17     while(ch>47&ch<='9')  s=s*10+(ch^48),ch=getchar();
     18     return s*k;
     19 }
     20  
     21 struct edges{
     22     int v;ll w;edges *last;
     23 }edge[N<<1],*head[N];int cnt;
     24  
     25 inline void push(int u,int v,ll w){
     26     edge[++cnt]=(edges){v,w,head[u]};head[u]=edge+cnt;
     27 }
     28  
     29 int n,up,low,tot,top,root,size[N],heavy[N],T[N],Tdis[N],part,from;
     30 ll t[N],dis[N];
     31 bool vis[N];
     32 double ans,maxr;
     33  
     34 inline void dfs(int x,int fa,int deep){
     35     size[x]=1;
     36     heavy[x]=0;
     37     for(edges *i=head[x];i;i=i->last)if(i->v!=fa&&(!vis[i->v])){
     38         dfs(i->v,x,deep+1);
     39         size[x]+=size[i->v];
     40         heavy[x]=max(size[i->v],heavy[x]);
     41     }
     42     heavy[x]=max(heavy[x],tot-size[x]);
     43     if(heavy[x]<top) 
     44         top=heavy[x],root=x;
     45 }
     46  
     47 inline void calc(int x,int fa,ll d,int lens){
     48     if(lens>up)  return ;
     49     if(Tdis[lens]!=part){
     50         Tdis[lens]=part;
     51         dis[lens]=d;
     52     }else
     53         dis[lens]=max(dis[lens],d);
     54     for(edges *i=head[x];i;i=i->last)    if(i->v!=fa&&(!vis[i->v])){
     55         calc(i->v,x,d+i->w,lens+1);
     56     }
     57 }
     58  
     59 inline void get_new(int x,int fa,ll d,int lens){
     60     if(lens>up)  return;
     61     if(T[lens]!=T[0])
     62         T[lens]=T[0],t[lens]=d;
     63     else   
     64         t[lens]=max(t[lens],d);
     65     from=max(from,lens);
     66     for(edges *i=head[x];i;i=i->last)    if(i->v!=fa&&(!vis[i->v])){
     67         get_new(i->v,x,d+i->w,lens+1);
     68     }
     69 }
     70  
     71 int q[N];
     72 double nq[N];
     73  
     74 inline bool Judge(double x){
     75     int l=0,r=0;
     76     int pos=min(up-1,from);
     77     bool flag=1;
     78     while(pos>=low){
     79         if(T[pos]!=T[0]){   
     80             pos--;continue;
     81         }
     82         while(r>l&&nq[r-1]<t[pos]-x*pos)
     83             r--;
     84         nq[r]=t[pos]-x*pos;
     85         q[r++]=pos;
     86         pos--;
     87     }
     88     for(int i=low-pos;i<=up;i++){
     89         if(Tdis[i]!=part)   break;
     90         if(pos>=0&&i+pos>=low&&T[pos]==T[0]){
     91             while(r>l&&nq[r-1]<t[pos]-x*pos)
     92                 r--;
     93             nq[r]=t[pos]-x*pos;
     94             q[r++]=pos;
     95         }
     96         while(l<r&&q[l]+i>up)
     97             l++;
     98         pos--;
     99         if(l<r&&nq[l]+dis[i]-i*x>=0)
    100             return true;
    101     }
    102     return false;
    103 }
    104  
    105 struct node{
    106     int v,w;
    107     friend bool operator <(node x,node y){
    108         return size[x.v]<size[y.v];
    109     }
    110 }sons[N];
    111  
    112  
    113 inline void solve(int u){
    114     tot=size[u];
    115     top=inf;
    116     dfs(u,u,0);
    117     vis[root]=true;
    118     T[0]++;
    119     from=1;
    120     int cc=0;
    121     for(edges *i=head[root];i;i=i->last)if(!vis[i->v]){
    122         cc++;
    123         sons[cc].v=i->v;
    124         sons[cc].w=i->w;
    125     }
    126     sort(sons+1,sons+1+cc);
    127     for(int i=1;i<=cc;i++){
    128         if(i>1){
    129                 part++;
    130                 calc(sons[i].v,0,sons[i].w,1);
    131                 double l=ans,r=maxr,mid;
    132                 while(l<r-eps){
    133                     mid=(l+r)/2;                
    134                     if(Judge(mid))  l=mid;
    135                     else    r=mid;
    136                 }
    137                 ans=l;
    138             }
    139             if(i<cc)
    140                 get_new(sons[i].v,0,sons[i].w,1);
    141     }
    142     for(edges *i=head[root];i;i=i->last) if(!vis[i->v])
    143         solve(i->v);
    144 }
    145  
    146 int main(){
    147     n=read();
    148     low=read(),up=read();
    149     for(int i=1,u,v,w;i<n;i++){
    150         u=read(),v=read(),w=read();
    151         push(u,v,w),push(v,u,w);
    152         maxr=max(maxr,w+0.0);
    153     }
    154     size[1]=n;
    155     solve(1);
    156     printf("%.3lf
    ",ans);
    157 }

     

  • 相关阅读:
    IOS8修改状态栏颜色
    iOS文件存储路径规定
    iOS+HTML5
    调用电话/获取通讯录
    iOS高级必备
    CoreData
    IOS 中的CoreImage框架
    CoreText
    CoreGpaphics
    iOS多线程 NSThread/GCD/NSOperationQueue
  • 原文地址:https://www.cnblogs.com/Troywar/p/7614422.html
Copyright © 2020-2023  润新知