zoukankan      html  css  js  c++  java
  • BZOJ 4901 [CTSC2017]网络

    题解:

    只会O(n log^2 n)

    O(n log n)先留坑

    不开long long 0 分!!!!

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=100009;
    const long long oo=1000000000000000LL;
    
    int n;
    long long c;
    
    int nn;
    long long k1[maxn];
    int pla[maxn];
    long long len[maxn];
    
    long long l,r,mid,ans;
    
    int cntedge=0;
    int head[maxn]={0};
    int to[maxn<<1],nex[maxn<<1],dist[maxn<<1];
    void Addedge(int x,int y,int z){
        nex[++cntedge]=head[x];
        to[cntedge]=y;
        dist[cntedge]=z;
        head[x]=cntedge;
    }
    
    int vis[maxn];
    int p[maxn],cntn;
    int lp,rp;
    int father[maxn];
    long long d[maxn];
    long long tmpd[maxn];
    
    void Dfs0(int now,int fa){
        father[now]=fa;
        for(int i=head[now];i;i=nex[i]){
            if(to[i]==fa)continue;
            d[to[i]]=d[now]+dist[i];
            Dfs0(to[i],now);
        }
    }
    void GetD(int x){
        vis[x]=1;
        if(father[x])GetD(father[x]);
        p[++cntn]=x;
    }
    long long Getdist(int x,int fa){
        long long ret=0;
        for(int i=head[x];i;i=nex[i]){
            if(to[i]==fa)continue;
            if(vis[to[i]])continue;
            ret=max(ret,dist[i]+Getdist(to[i],x));
        }
        return ret;
    }
    
    struct FenwickTree{
        long long c[maxn];
        void Addp(int x,long long val){
            while(x<=nn){
                c[x]=max(c[x],val);
                x+=(x&(-x));
            }
        }
        long long Querymax(int x){
            long long ret=-oo;
            while(x){
                ret=max(ret,c[x]);
                x-=(x&(-x));
            }
            return ret;
        }
        void Clea(){
            for(int i=1;i<=nn;++i)c[i]=-oo;
        }
    }T[2];
    
    int Isok(){
        long long lim1=-oo,lim2=-oo,lim3=-oo,lim4=-oo;
        
        T[0].Clea();T[1].Clea();
        for(int i=1;i<=cntn;++i){
            int p=lower_bound(k1+1,k1+1+nn,d[i]+len[i]-mid)-k1;
            long long mxsum=T[0].Querymax(p-1);
            long long mxdelt=T[1].Querymax(p-1);
            lim1=max(lim1,d[i]+len[i]+mxsum+c-mid);
            lim2=max(lim2,-d[i]+len[i]+mxsum+c-mid);
            lim3=max(lim3,d[i]+len[i]+mxdelt+c-mid);
            lim4=max(lim4,-d[i]+len[i]+mxdelt+c-mid);
            T[0].Addp(pla[i],d[i]+len[i]);
            T[1].Addp(pla[i],-d[i]+len[i]);
        }
    
        int p1=1,p2=1;
        int fla=0;
        for(int i=1;i<=cntn;++i){
            long long tl=max(lim1-d[i],lim2+d[i]);
            long long tr=min(-lim3+d[i],-lim4-d[i]);
            if(tl>tr)continue;
            while((d[p1]<tl)&&(p1<=cntn))++p1;
            while((d[p1-1]>=tl)&&(p1>1))--p1;
            while((d[p2+1]<=tr)&&(p2<cntn))++p2;
            while((d[p2]>tr)&&(p2>=1))--p2;
            if(p1<=p2){
                fla=1;break;
            }
        }
        return fla;
    }
    
    void Minit(){
        cntn=lp=rp=cntedge=nn=0;
        l=0;r=oo;ans=oo;
        memset(len,0,sizeof(len));
        memset(head,0,sizeof(head));
        memset(vis,0,sizeof(vis));
        memset(p,0,sizeof(p));
        memset(father,0,sizeof(father));
        memset(d,0,sizeof(d));
    }
    
    int main(){
        scanf("%d%lld",&n,&c);
        while(n!=0){
            Minit();
            for(int i=1;i<=n-1;++i){
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                Addedge(x,y,z);
                Addedge(y,x,z);
            }
            d[1]=0;
            Dfs0(1,0);
            for(int i=1;i<=n;++i){
                if(d[i]>d[lp])lp=i;
            }
            d[lp]=0;
            Dfs0(lp,0);
            for(int i=1;i<=n;++i){
                if(d[i]>d[rp])rp=i;
            }
            
            for(int i=1;i<=n;++i)tmpd[i]=d[i];
            GetD(rp);
            for(int i=1;i<=cntn;++i)len[i]=Getdist(p[i],0);
            for(int i=1;i<=cntn;++i)l=max(l,len[i]);
            for(int i=1;i<=cntn;++i)d[i]=tmpd[p[i]];
            
            for(int i=1;i<=cntn;++i)k1[i]=d[i]-len[i];
            sort(k1+1,k1+1+cntn);
            nn=unique(k1+1,k1+1+cntn)-k1-1;
            for(int i=1;i<=cntn;++i)pla[i]=lower_bound(k1+1,k1+1+nn,d[i]-len[i])-k1;
            
            r=l*2+d[cntn];
            while(l<=r){
                mid=(l+r)>>1;
                if(Isok()){
                    ans=mid;r=mid-1;
                }else{
                    l=mid+1;
                }
            }
            cout<<ans<<endl;
            
            scanf("%d%lld",&n,&c);
        }
        return 0;
    }
    自己还是太辣鸡了
  • 相关阅读:
    SQL Server 的事务和锁(一)
    Sql server脏读、更新丢失、不可重复读、幻象读问题及解决方案
    Sql server锁机制
    Windows系统变量列表
    windows运行命令大全
    C# 捕获数据库自定义异常
    sql日期函数
    C# ado.net 操作存储过程(二)
    C# ado.net 操作(一)
    url传参特殊字符问题(+、%、#等)
  • 原文地址:https://www.cnblogs.com/zzyer/p/8609634.html
Copyright © 2011-2022 走看看