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;
}
自己还是太辣鸡了
原文地址:https://www.cnblogs.com/zzyer/p/8609634.html