• 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;
    }
    自己还是太辣鸡了
  • 相关阅读:
    如何用CSS实现中间自适应,两边定宽三栏布局
    [转]通过Spring Boot三分钟创建Spring Web项目
    [转]Java Web笔记:搭建环境和项目配置(MyEclipse 2014 + Maven + Tomcat)
    [转]单元测试、集成测试、确认测试、系统测试、验收测试
    [转]maven全局配置文件settings.xml详解
    [转]解决-Dmaven.multiModuleProjectDirectory system property is not set. Check $M2_HOME environment variable and mvn script match.
    [转]PO BO VO DTO POJO DAO概念及其作用(附转换图)
    [转]如何提升你的能力?给年轻程序员的几条建议
    从oracle导出数据成csv,将csv导入mongodb问题
    Windows下Mongodb启动问题
  • 原文地址:https://www.cnblogs.com/zzyer/p/8609634.html
Copyright © 2020-2023  润新知