hdu 4123 Bob’s Race 树形dp+单调队列

树形dp求树上最长距离,然后单调队列维护。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int maxn=5e4+9;
vector < pair<int,int> > e[maxn];
int n,m;
int dist[maxn][2];

void dfs(int t,int from)
{
    for(vector < pair<int,int> >::iterator k=e[t].begin();k!=e[t].end();k++)
    {
        int u=k->first,w=k->second;
        if(u==from) continue;
        dfs(u,t);
        if(dist[u][0]+w>dist[t][0])
        {
            dist[t][1]=dist[t][0];
            dist[t][0]=dist[u][0]+w;
        }
        else if(dist[u][0]+w>dist[t][1])
        {
            dist[t][1]=dist[u][0]+w;
        }
    }
}

void dfs2(int t,int from)
{
    for(vector < pair<int,int> >::iterator k=e[t].begin();k!=e[t].end();k++)
    {
        int u=k->first,w=k->second,sum;
        if(u==from) continue;
        if(dist[t][0]!=w+dist[u][0]) sum=dist[t][0]+w;
        else sum=dist[t][1]+w;
        if(sum>dist[u][0])
        {
            dist[u][1]=dist[u][0];
            dist[u][0]=sum;
        }
        else if(sum>dist[u][1])
        {
            dist[u][1]=sum;
        }
        dfs2(u,t);
    }
}
struct
{
    int que[maxn],id[maxn];
    int st,ed;
}mmax,mmin;
void getans(int tmp)
{
    int ans=0;
    mmax.st=mmin.st=1;
    mmax.ed=mmin.ed=0;
    int id=0;
    for(int i=1;i<=n;i++)
    {
        while(mmax.ed>=mmax.st&&mmax.que[mmax.ed]<dist[i][0])
        mmax.ed--;
        mmax.que[++mmax.ed]=dist[i][0];
        mmax.id[mmax.ed]=i;

        while(mmin.ed>=mmin.st&&mmin.que[mmin.ed]>dist[i][0])
        mmin.ed--;
        mmin.que[++mmin.ed]=dist[i][0];
        mmin.id[mmin.ed]=i;

        while(mmax.que[mmax.st]-mmin.que[mmin.st]>tmp)
        {
            if(mmin.st==mmin.ed)
            {
                id=max(id,mmax.id[mmax.st]);
                mmax.st++;
            }
            else if(mmax.st==mmax.ed)
            {
                id=max(id,mmin.id[mmin.st]);
                mmin.st++;
            }
            else if(mmax.id[mmax.st]<mmin.id[mmin.st])
            {
                id=max(id,mmax.id[mmax.st]);
                mmax.st++;
            }
            else
            {
                id=max(id,mmin.id[mmin.st]);
                mmin.st++;
            }
        }
        ans=max(ans,i-id);
    }
    cout<<ans<<endl;
}


int main()
{
//    freopen("in.txt","r",stdin);
    while(scanf("%d%d",&n,&m),n||m)
    {
        for(int i=1;i<=n;i++) e[i].clear();
        for(int i=1,from,to,w;i<n;i++)
        {
            scanf("%d%d%d",&from,&to,&w);
            e[from].push_back(make_pair(to,w));
            e[to].push_back(make_pair(from,w));
        }
        memset(dist,0,sizeof(dist));
        dfs(1,-1);
        dfs2(1,-1);
        for(int i=1,tmp;i<=m;i++)
        {
            scanf("%d",&tmp);
            getans(tmp);
        }
    }
    return 0;
}


你可能感兴趣的:(hdu 4123 Bob’s Race 树形dp+单调队列)