zoukankan      html  css  js  c++  java
  • Noip2015 运输计划 树上差分 二分答案

    Code:

    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<string>
    using namespace std;
    void setIO(string a){freopen((a+".in").c_str(),"r",stdin);}
    #define maxn 300090
    #define logn 20
    int head[maxn],to[maxn<<1],nex[maxn<<1],val[maxn<<1];
    int f[logn][maxn],maxv[logn][maxn],sumv[logn][maxn],dep[maxn],tot[maxn];
    int edges,n,m,delta,flag, max_delta;
    struct Query{
        int u,v,len,tag,lca;
    }query[maxn];
    void addedge(int u,int v,int c){
        nex[++edges]=head[u],head[u]=edges,to[edges]=v,val[edges]=c;
    }
    void dfs(int u,int fa,int depth,int c){
        f[0][u]=fa,dep[u]=depth,sumv[0][u]=maxv[0][u]=c;
        for(int i=1;i<logn;++i){
            f[i][u]=f[i-1][f[i-1][u]];
            sumv[i][u]=sumv[i-1][u]+sumv[i-1][f[i-1][u]];
            maxv[i][u]=max(maxv[i-1][u],maxv[i-1][f[i-1][u]]);
        }
        for(int v=head[u];v;v=nex[v]){
            if(to[v]==fa)continue;
            dfs(to[v],u,depth+1,val[v]);
        }
    }
    int LCA(int a,int b,int &qmax,int &qsum){
        qmax=qsum=0;
        if(dep[a]>dep[b])swap(a,b);
        if(dep[a]!=dep[b]) 
            for(int i=logn-1;i>=0;--i)
                if(dep[f[i][b]]>=dep[a]) {
                    qmax=max(qmax,maxv[i][b]);
                    qsum+=sumv[i][b];
                    b=f[i][b];
                }
        if(a==b)return a;
        for(int i=logn-1;i>=0;--i) 
            if(f[i][a]!=f[i][b]){
                qmax=max(qmax,max(maxv[i][a],maxv[i][b]));
                qsum+=(sumv[i][b]+sumv[i][a]);
                b=f[i][b],a=f[i][a];
            }
        qmax=max(qmax,max(maxv[0][a],maxv[0][b]));
        qsum+=(sumv[0][a]+sumv[0][b]);
        return f[0][a];
    }
    int release(int u,int fa){
        int cur=tot[u];
        for(int v=head[u];v;v=nex[v]){
            if(to[v]==fa)continue;
            cur+=release(to[v],u);
        }
        if(cur>=delta&&sumv[0][u]>=max_delta) flag=1;
        return cur;
    }
    bool check(int tps){
        delta=0,flag=0,max_delta=0;
        for(int i=1;i<=m;++i) {
            if(query[i].len-query[i].tag>tps) return false;
            if(query[i].len>tps) 
                ++delta, max_delta=max(max_delta,query[i].len-tps);     
        }
        if(delta==0) return true;
        memset(tot,0,sizeof(tot));
        for(int i=1;i<=m;++i)
            if(query[i].len>tps){
                int a=query[i].u,b=query[i].v;
                tot[a]++,tot[b]++;
                tot[query[i].lca]-=2;
            }
        release(1,0);
        return flag;
    }
    int main(){
        //setIO("input");
        scanf("%d%d",&n,&m);
        for(int i=1;i<n;++i){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            addedge(a,b,c);
            addedge(b,a,c);
        }
        dfs(1,0,1,0);
        for(int i=1;i<=m;++i){
            scanf("%d%d",&query[i].u,&query[i].v);
            query[i].lca=LCA(query[i].u,query[i].v,query[i].tag,query[i].len);
        }
        int l=0,r=1500000000,mid,ans=0;
        while(l<=r){
            mid=(l+r)>>1;
            if(check(mid)) ans=mid,r=mid-1;
            else l=mid+1;
        }
        printf("%d",ans);
        return 0;
    }
    

      

  • 相关阅读:
    可在广域网部署运行的QQ高仿版 -- GG叽叽(源码)
    区间合并
    二分查找算法模板
    神经网络详解(RNN/LSTM)
    反向传播算法推导过程(非常详细)
    机器学习-回归问题(Regression)
    从RNN到LSTM
    神经网络浅讲:从神经元到深度学习
    部署高并发python后端(Systemd+Nginx+Gunicorn+Gevent+Supervisor+Flask )
    产品笔记 | 软件版本号—规范与命名规则
  • 原文地址:https://www.cnblogs.com/guangheli/p/9926525.html
Copyright © 2011-2022 走看看