POJ - 3162-Walking Race (tree dp + monotone queue)

Topic: Give a tree with weights on the edges of n nodes, and remember that the farthest distance from node i to other nodes is d[i].

The length of a continuous subsequence that satisfies the difference between the maximum value and the minimum value in the sequence composed of d arrays is not more than m.

use Tree dp To find the maximum distance from each vertex in the tree to all other vertices. Then, monotone queues are used to find the longest continuous subsequence satisfying max-min<=m.

//#include <bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#include<cstring>

using namespace std;
typedef long long ll;
const int maxn=1e6+100;
struct node{
    int x;
    ll w;
    node(int _x,ll _w)
    {
        x=_x;
        w=_w;
    }
};
vector<node>a[maxn];
int n;
ll m,dp[maxn],dpf[maxn];
void dfs(int u,int fa)
{
    for(int i=0;i<a[u].size();i++)
    {
        int v=a[u][i].x;
        if(v==fa) continue;
        dfs(v,u);
        dp[u]=max(dp[u],dp[v]+a[u][i].w);
    }
}
void DFS(int u,int fa)
{
    ll tmp1=0,tmp2=0;
    int x,y;
    for(int i=0;i<a[u].size();i++)
    {
        int v=a[u][i].x;
        if(v==fa) continue;
        if(tmp2<dp[v]+a[u][i].w)
        {
            tmp2=dp[v]+a[u][i].w;
            y=v;
            if(tmp1<tmp2)
            {
                swap(tmp1,tmp2);
                swap(x,y);
            }
        }
    }

    for(int i=0;i<a[u].size();i++)
    {
        int v=a[u][i].x;
        ll w=a[u][i].w;
        if(v==fa) continue;
        if(v==x)
            dpf[v]=max(dpf[u],tmp2)+w;
        else dpf[v]=max(dpf[u],tmp1)+w;
        DFS(v,u);
    }
}
ll c[maxn],q[maxn],p[maxn];
int main()
{
    ///cout << "Hello world!" << endl;
    ///freopen("in.txt","r",stdin);
    while(~scanf("%d%lld",&n,&m))
    {
        for(int i=1;i<=n;i++)
            a[i].clear();
        for(int i=2;i<=n;i++)
        {
            int j;ll w;
            scanf("%d%lld",&j,&w);
            a[j].push_back(node(i,w));
        }
        memset(dp,0,sizeof dp);
        memset(dpf,0,sizeof dpf);
        dfs(1,0);
        DFS(1,0);
        for(int i=1;i<=n;i++)
            c[i]=max(dp[i],dpf[i]);
        /*-------------------------------*/
        //The sequence is c.
        //How long is the longest continuous subsequence satisfying max-min<=m for monotone queues
        int ans=0;
        int tail1=0,tail2=0,head1=1,head2=1,pre=1;
        for(int i=1;i<=n;i++)
        {
            while(tail1>=head1&&c[q[tail1]]>=c[i])
                tail1--;
            q[++tail1]=i;

            while(tail2>=head2&&c[p[tail2]]<=c[i])
                tail2--;
            p[++tail2]=i;
            if(c[p[head2]]-c[q[head1]]>m)
            {
                ans=max(i-pre,ans);
                if(q[head1]<p[head2])
                {
                    pre=q[head1]+1;
                    head1++;
                }
                else
                {
                    pre=p[head2]+1;
                    head2++;
                }
            }
        }
        ans=max(ans,n+1-pre);//Don't drop this sentence.

        /*-------------------------------*/
        printf("%d\n",ans);
    }
    return 0;
}


Posted by jd023 on Mon, 04 Feb 2019 17:39:16 -0800