• BZOJ 1758: [Wc2010]重建计划 01分数规划+点分治+单调队列


    code: 

    #include <bits/stdc++.h>     
    using namespace std; 
    #define setIO(s) freopen(s".in","r",stdin)  
    const int N=200006;  
    const double eps=1e-6;     
    const double inf=-100000000;              
    struct node
    {
        int u,dep,val; 
        node(int u=0,int dep=0,int val=0):u(u),dep(dep),val(val){}    
    };     
    struct data 
    {
        int len; 
        double dis; 
        data(int len=0,double dis=0.0):len(len),dis(dis){}  
    };   
    bool cmp(node a,node b) { return a.dep<b.dep; }  
    deque<data>q;        
    vector<node>G[N];      
    vector<int>tree[N];    
    int n,L,R,edges,root; 
    int hd[N],to[N<<1],nex[N<<1],val[N<<1];         
    int size[N],mx[N],vis[N],sn,max_dep,RT;                 
    double maxv[N],tmp[N],mid;
    inline void add(int u,int v,int c) 
    {
        nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c;   
    }              
    void getroot(int u,int ff) 
    { 
        size[u]=1,mx[u]=0;  
        for(int i=hd[u];i;i=nex[i]) 
        {
            int v=to[i]; 
            if(v==ff||vis[v])    continue;   
            getroot(v,u);   
            size[u]+=size[v];   
            mx[u]=max(mx[u],size[v]);  
        }   
        mx[u]=max(mx[u],sn-size[u]);   
        if(mx[u]<mx[root])    root=u;      
    }   
    void getdis(int u,int ff,int d) 
    {     
        max_dep=max(max_dep,d);  
        for(int i=hd[u];i;i=nex[i])   if(to[i]!=ff&&!vis[to[i]])    getdis(to[i],u,d+1);  
    }
    void prepare(int u) 
    { 
        vis[u]=1;             
        for(int i=hd[u];i;i=nex[i]) 
        {
            int v=to[i];  
            if(vis[v])    continue;                 
            max_dep=0; 
            getdis(v,u,1);                  
            G[u].push_back(node(v,max_dep,val[i]));                          
        }   
        sort(G[u].begin(),G[u].end(),cmp);    
        for(int i=hd[u];i;i=nex[i])  
        {
            int v=to[i]; 
            if(vis[v])    continue;
            sn=size[v];    
            root=0;   
            getroot(v,u);        
            tree[u].push_back(root);    
            prepare(root);  
        }
    }    
    void dfs(int u,int ff,int d,double dis) 
    {   
        maxv[d]=max(maxv[d],dis);                        
        for(int i=hd[u];i;i=nex[i])  
        {
            int v=to[i]; 
            if(v==ff||vis[v])    continue;    
            dfs(v,u,d+1,dis+val[i]-mid);        
        }   
    }  
    int calculate(int u) 
    {     
        int flag=0;    
        for(int i=0;i<G[u].size();++i) 
        {   
            int v=G[u][i].u;                   
            dfs(v,u,1,G[u][i].val-mid);       
            for(int j=1;j<=G[u][i].dep;++j)  if(maxv[j]>=-eps&&j>=L&&j<=R)   { flag=1;   break; }                                          
            if(i)      
            {
                int tl=min(R,G[u][i-1].dep);   
                for(int j=1;j<=min(R,G[u][i].dep);++j) 
                {                         
                    for(;tl>=L-j&&tl>0;--tl)      
                    {
                        while(!q.empty()&&(tmp[tl]-eps)>=q.front().dis) q.pop_front();                                  
                        q.push_front(data(tl,tmp[tl]));                                          
                    }                  
                    while(!q.empty()&&q.back().len>R-j)  q.pop_back(); 
                    if(!q.empty()) 
                    {                       
                        if(maxv[j]+q.back().dis>=-eps)  
                        {             
                            flag=1;              
                            break;  
                        }
                    }
                }
            }
            while(!q.empty())    q.pop_front();   
            if(flag)    break;     
            for(int j=1;j<=G[u][i].dep;++j)   tmp[j]=max(tmp[j],maxv[j]); 
            for(int j=0;j<=G[u][i].dep;++j)   maxv[j]=inf;  
        }            
        if(G[u].size()) 
        {
            for(int i=0;i<=G[u][G[u].size()-1].dep;++i)   tmp[i]=maxv[i]=inf;            
        }  
        while(!q.empty())    q.pop_front();    
        return flag;                       
    }
    int solve(int u) 
    {   
        vis[u]=1;   
        if(calculate(u))    return 1;      
        for(int i=0;i<tree[u].size();++i)      if(solve(tree[u][i]))   return 1;     
        return 0;   
    }   
    int main() 
    { 
        // setIO("input"); 
        int i,j;      
        scanf("%d%d%d",&n,&L,&R);         
        for(i=1;i<n;++i) 
        { 
            int x,y,z; 
            scanf("%d%d%d",&x,&y,&z); 
            add(x,y,z),add(y,x,z);  
        }          
        mx[0]=sn=n;   
        getroot(1,0);    
        RT=root;  
        prepare(root);       
        double l=0.0,r=1000000.0;       
        for(i=0;i<N;++i)   maxv[i]=tmp[i]=inf;       
        for(int i=33;i>=1;--i) 
        {
            mid=(l+r)/2;       
            memset(vis,0,sizeof(vis));        
            if(solve(RT))   
            {      
                l=mid;            
            }
            else 
            {     
                r=mid; 
            } 
        }                               
        printf("%.3f
    ",l);    
        return 0; 
    }
    

      

  • 相关阅读:
    PAT Advanced 1008 Elevator (20) [数学问题-简单数学]
    PAT Advanced 1051 Pop Sequence (25) [栈模拟]
    PAT Basic 完美数列(25) [two pointers]
    PAT Basic 插⼊与归并(25) [two pointers]
    PAT Advanced 1089 Insert or Merge (25) [two pointers]
    第五章 数据的共享和保护
    第四章 面向对象程序设计的基本特点 课堂笔记
    第三章 函数 课堂笔记
    扫描线-Meteor UVALive
    贪心-Stall Reservations POJ
  • 原文地址:https://www.cnblogs.com/guangheli/p/11959569.html
Copyright © 2020-2023  润新知