• 【bzoj2500】幸福的道路 【树形dp】【单调队列优化dp】


    题目链接
    强行拼题。。。
    先是经典的树上最长路的树形dp,然后单调队列优化dp就好了。时间复杂度O(n)
    怎么树d,我之前好像写过。。。这里的T6就是
    代码

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=1000005;
    int n,u,cnt,ans=1,f1,r1,f2,r2,head[N],q1[N*2],q2[N*2],to[N*2],nxt[N*2];
    ll m,d,dd[N*2],f[N][3];
    void adde(int u,int v,ll d){
        to[++cnt]=v;
        nxt[cnt]=head[u];
        dd[cnt]=d;
        head[u]=cnt;
    }
    void dfs1(int pre,int u){
        int v;
        for(int i=head[u];i;i=nxt[i]){
            v=to[i];
            if(v!=pre){
                dfs1(u,v);
                if(f[v][0]+dd[i]>f[u][0]){
                    f[u][1]=f[u][0];
                    f[u][0]=f[v][0]+dd[i];
                }else if(f[v][0]+dd[i]>f[u][1]){
                    f[u][1]=f[v][0]+dd[i];
                }
            }
        }
        f[u][2]=f[u][0];
    }
    void dfs2(int pre,int u,ll d){
        f[u][2]=max(f[u][2],d);
        int v;
        for(int i=head[u];i;i=nxt[i]){
            v=to[i];
            if(v!=pre){
                if(f[v][0]+dd[i]==f[u][0]){
                    dfs2(u,v,max(d,f[u][1])+dd[i]);
                }else{
                    dfs2(u,v,max(d,f[u][0])+dd[i]);
                }
            }
        }
    }
    int main(){
        scanf("%d%lld",&n,&m);
        for(int i=2;i<=n;i++){
            scanf("%d%lld",&u,&d);
            adde(u,i,d);
            adde(i,u,d);
        }
        dfs1(0,1);
        dfs2(0,1,0);
        q1[f1=r1=1]=1;
        q2[f2=r2=1]=1;
        for(int i=2,j=1;i<=n;i++){
            while(f1<=r1&&q1[f1]<j){
                f1++;
            }
            while(f2<=r2&&q2[f2]<j){
                f2++;
            }
            while(f1<=r1&&f[q1[r1]][2]<f[i][2]){
                r1--;
            }
            q1[++r1]=i;
            while(f2<=r2&&f[q2[r2]][2]>f[i][2]){
                r2--;
            }
            q2[++r2]=i;
            while(f1<=r1&&f2<=r2&&f[q1[f1]][2]-f[q2[f2]][2]>m){
                j++;
                while(f1<=r1&&q1[f1]<j){
                    f1++;
                }
                while(f2<=r2&&q2[f2]<j){
                    f2++;
                }
            }
            ans=max(ans,i-j+1);
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    Intern Day5
    PTA1007
    Intern Day5
    Intern Day2
    Intern Day5
    Intern Day2
    Intern Day2
    Intern Day2
    Intern Day1
    柯南剧场版17绝海的侦探
  • 原文地址:https://www.cnblogs.com/2016gdgzoi471/p/9476839.html
Copyright © 2020-2023  润新知