[BZOJ3242] [Noi2013] Fast food restaurant (tree-shaped dp+ line tree)

Source: Internet
Author: User
Tags min
Title Description

Portal

If the title is given to a tree, the answer should clearly be the diameter of the tree/2.
But the title is a ring-set tree, then if we violently delete a side of the ring and then create a tree of the longest chain, and then take Min, of course, is correct, but the time complexity is O (n2) O (n^2) unbearable.
So we can consider this: because to make the longest chain shortest, then our task is to find a tree shape, so that the longest chain in this case in all cases the shortest.

First, the force of the ring is necessary, time complexity O (n) o (n).
Then consider two things:
① if the longest chain does not pass through the ring, that is, the longest strand is in the outer tree, then each point on the loop is enumerated, and then the DP is carried out on each outward tree, so that the longest chain in the tree can be obtained. Time complexity O (n) o (n)
② if the longest chain passes through the ring, it is clear that it will not pass through an edge on the ring (similar to the idea of deleting edges). Suppose S[i] represents the longest distance from the root to the leaf node of an outward tree with the roots of I, sum[i] is the prefix of the distance and (the currently deleted edge regardless of the remainder becomes a sequence), then the longest chain should be max{sum[i]−sum[j]+s[i]+s[j]}=max{( Sum[i]+s[i]) − (sum[j]+s[j])}=max{sum[i]+s[i]}−min{sum[j]+s[j]} max\{sum[i]-sum[j]+s[i]+s[j]\}=max\{(Sum[i]+s[i]) -(Sum[j]+s[j]) \}=max\{sum[i]+s[i]\}-min\{sum[j]+s[j]\}. It can be seen that two line-segment trees can be maintained, but because I cannot be equal to J, it is also necessary to maintain the secondary and minor values. It would be nice to modify the values in the segment tree during enumeration. Time complexity O (NLOGN) O (Nlogn).
It is important to note that the first case should be all the longest chain to Max, that is no matter the deletion of the answer is not smaller than the longest chain on the outgoing tree. But the second case should take min, thinking that a set of optimal solutions should be obtained by deleting the edges. Finally, the answers to the two cases are taken max. Code

#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <
Ctime> using namespace std;
#define N 100005 #define LL long long int n,x,y,cnt,last;
LL z,max1,max2,ans1,ans2,ans,t,lastsum; int tot,point[n],nxt[n*2],v[n*2];
LL C[n*2];
int father[n],o[n];
LL Len[n],length[n],f[n],g[n],s[n],sum[n],delta[n*4];
BOOL Vis[n],flag; struct hp{ll val;int num;}

MAXN[N*4],_MAXN[N*4],MINN[N*4],_MINN[N*4],A[5];
    inline int read () {char ch=getchar (); int x=0; while (ch< ' 0 ' | |
    Ch> ' 9 ') Ch=getchar ();
    while (ch>= ' 0 ' &&ch<= ' 9 ') x=x*10+ch-' 0 ', Ch=getchar ();
return x;
    } inline void Addedge (int x,int y,ll z) {++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; c[tot]=z; ++tot; Nxt[tot]=point[y]; Point[y]=tot; V[tot]=x;
C[tot]=z;
        } inline void Circle (int x,int pt) {while (x!=pt) {o[++cnt]=x;
    X=FATHER[X];
} o[++cnt]=pt;
    } inline void Dfs (int x,int fa) {vis[x]=true; father[x]=fa;for (int i=point[x];i&& (!flag); I=nxt[i]) if (V[I]!=FA) {len[v[i]]=c[i];
                if (Vis[v[i]]) {Circle (x,v[i]);
                Flag=true;
            Break
        } dfs (V[I],X);
        }} inline void treedp (int x,int fa) {for (int i=point[x];i;i=nxt[i]) if (V[i]!=fa&&!vis[v[i]])
            {TREEDP (v[i],x);
                if (F[v[i]]+c[i]>f[x]) {g[x]=f[x];
            F[x]=f[v[i]]+c[i];
        } else G[x]=max (G[x],f[v[i]]+c[i]);
    } max1=max (Max1,f[x]+g[x]);
Max2=max (Max2,f[x]); 
} inline int Cmpmax (HP a,hp b) {return a.val>b.val;} inline int cmpmin (HP a,hp b) {return a.val<b.val;}
    inline void update (int now) {a[1].val=maxn[now<<1].val,a[1].num=maxn[now<<1].num;
    a[2].val=maxn[now<<1|1].val,a[2].num=maxn[now<<1|1].num; A[3].VAL=_MAXN[NOW&LT;&LT;1].val,a[3].num=_maxn[now<<1].num;
    a[4].val=_maxn[now<<1|1].val,a[4].num=_maxn[now<<1|1].num;

    Sort (A+1,a+5,cmpmax);
    Maxn[now].val=a[1].val,maxn[now].num=a[1].num; for (int i=2;i<=4;++i) if (a[i].num!=maxn[now].num) {_maxn[now].val=a[i].val,_maxn[now].nu
            M=a[i].num;
        Break
    } a[1].val=minn[now<<1].val,a[1].num=minn[now<<1].num;
    a[2].val=minn[now<<1|1].val,a[2].num=minn[now<<1|1].num;
    a[3].val=_minn[now<<1].val,a[3].num=_minn[now<<1].num;
    a[4].val=_minn[now<<1|1].val,a[4].num=_minn[now<<1|1].num;

    Sort (a+1,a+5,cmpmin);
    Minn[now].val=a[1].val,minn[now].num=a[1].num; for (int i=2;i<=4;++i) if (a[i].num!=minn[now].num) {_minn[now].val=a[i].val,_minn[now].nu
            M=a[i].num;
        Break
    }} inline void build (int now,int l,int r) {int mid= (L+R) >>1; if (l==r) {Maxn[now]. Val=_maxn[now].val=sum[l]+s[l];
        MINN[NOW].VAL=_MINN[NOW].VAL=SUM[L]-S[L];
        Maxn[now].num=_maxn[now].num=minn[now].num=_minn[now].num=l;
    Return
    } build (Now<<1,l,mid);
    Build (Now<<1|1,mid+1,r);
Update (now); } inline void pushdown (int now,int l,int R,int mid) {if (Delta[now]) {Maxn[now<<1].val+=delta[now] ;
        _maxn[now<<1].val+=delta[now]; minn[now<<1].val+=delta[now];
        _minn[now<<1].val+=delta[now]; maxn[now<<1|1].val+=delta[now];
        _maxn[now<<1|1].val+=delta[now]; minn[now<<1|1].val+=delta[now];
        _minn[now<<1|1].val+=delta[now]; delta[now<<1]+=delta[now];
        delta[now<<1|1]+=delta[now];
    delta[now]=0;
    }} inline void Interval_change (int now,int l,int r,int lrange,int rrange,ll v) {int mid= (L+R) >>1;
        if (lrange<=l&&r<=rrange) {maxn[now].val+=v; _maxn[now].val+=v; Minn[now].val+=v;
        _minn[now].val+=v;
        Delta[now]+=v;
    Return
    } pushdown (Now,l,r,mid);
    if (lrange<=mid) Interval_change (NOW&LT;&LT;1,L,MID,LRANGE,RRANGE,V);
    if (mid+1<=rrange) Interval_change (NOW&LT;&LT;1|1,MID+1,R,LRANGE,RRANGE,V);
Update (now);
    } inline LL query () {if (maxn[1].num!=minn[1].num) return maxn[1].val-minn[1].val;
else return Max (maxn[1].val-_minn[1].val,_maxn[1].val-minn[1].val);
    } int main () {n=read ();
        for (int i=1;i<=n;++i) {x=read (); Y=read (); Z=read ();
    Addedge (x, Y, (LL) z);

    } dfs (1,0);
    for (int i=1;i<=cnt;++i) length[i]=len[o[i]];
    memset (vis,0,sizeof (VIS));
    for (int i=1;i<=cnt;++i) vis[o[i]]=true;
        for (int i=1;i<=cnt;++i) {max1=max2=0;
        TREEDP (o[i],0);
        Ans1=max (ANS1,MAX1);
    S[I]=MAX2;

    } for (int i=1;i<cnt;++i) sum[i+1]=sum[i]+length[i];
    Build (1,1,CNT);
    T=query ();
    ans2=t;
    LASTSUM=SUM[CNT]; Last=cnt;
        for (int i=1;i<cnt;++i) {interval_change (1,1,cnt,1,cnt,-length[i]);
        Interval_change (1,1,cnt,i,i,lastsum+length[last]);
        T=query ();
        Ans2=min (ans2,t);
        Lastsum=lastsum-length[i]+length[last];
    last=i;
    } ans=max (ANS1,ANS2);
    Double loc= (double) ans/2;
printf ("%0.1lf\n", loc); }
Summary

①memset is very slow, time should be O (

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.