zoukankan      html  css  js  c++  java
  • hdu 4123 Bob’s Race(树形DP+rmq)

    题目链接:hdu 4123 Bob’s Race

    题意:

    给你n个节点,n-1条边的树,每条边有一个边权,定义dis[i]为距离i这个点最远的距离。

    现在有m个询问,每个询问给一个q,然后找一段节点标号连续的点,使得max(dis[j])-min(dis[i])<=q;

    问最长的一段区间。

    题解:

    最开始还以为这个连续指的是有边相连,然后感觉无法做啊,然后百度了一下,发现是标号的相连。

    先求出每一个点的dis,如果不会,请先做hdu 2196 Computer(树形DP)

    因为m比较小,我们就可以考虑对每个询问用双指针滚一下。

    然后双指针滚的时候要求每段区间的最大值和最小值,所以这里用rmq预处理一下最大和最小值,

    或者也可以用单调队列维护一下  都行。

     1 #include<bits/stdc++.h>
     2 #define F(i,a,b) for(int i=a;i<=b;i++)
     3 using namespace std;
     4 const int N=5e4+7;
     5 int n,m,g[N],v[2*N],nxt[N*2],w[N*2],ed,dis[N],en,mx,mxx[N][20],mii[N][20];
     6 
     7 void adg(int x,int y,int z){v[++ed]=y,w[ed]=z,nxt[ed]=g[x],g[x]=ed;}
     8 
     9 void dfs(int x,int fa,int dep)
    10 {
    11     dis[x]=max(dis[x],dep);
    12     if(dep>mx)mx=dep,en=x;
    13     for(int i=g[x];i;i=nxt[i])
    14         if(v[i]!=fa)dfs(v[i],x,dep+w[i]);
    15 }
    16 
    17 void rmq(int *a,int f[][20],int k)
    18 {
    19     F(i,1,n)f[i][0]=a[i];
    20     for(int j=1;1<<j<n;j++)F(i,1,n)
    21     if(i+(1<<j)-1<= n)
    22     f[i][j]=k?max(f[i][j-1],f[i+(1<<j-1)][j-1]):min(f[i][j-1],f[i+(1<<j-1)][j-1]);
    23     else break;
    24 }
    25 inline int find(int l,int r,int v)
    26 {
    27     int k=31-__builtin_clz(r-l+1);
    28     return v?max(mxx[l][k],mxx[r-(1<<k)+1][k]):min(mii[l][k],mii[r-(1<<k)+1][k]);
    29 }
    30 
    31 int find(int x)
    32 {
    33     int l=1,r=0,ans=0,mxx=0,mii=-N;
    34     while(r<n)
    35     {
    36         while(r<n&&(l>r||find(l,r+1,1)-find(l,r+1,0)<=x))r++;
    37         ans=max(ans,r-l+1),r++;
    38         if(r>n)break;
    39         while(l<r&&find(l,r,1)-find(l,r,0)>x)l++;
    40         ans=max(ans,r-l+1);
    41     }
    42     return ans;
    43 }
    44 
    45 int main()
    46 {
    47     while(scanf("%d%d",&n,&m),n+m)
    48     {
    49         memset(g,0,sizeof(g)),ed=mx=0;
    50         int x,y,z;
    51         F(i,1,n-1)
    52         {
    53             scanf("%d%d%d",&x,&y,&z);
    54             adg(x,y,z),adg(y,x,z);
    55         }
    56         F(i,1,n)dis[i]=0;
    57         dfs(1,0,0),dfs(en,0,0),dfs(en,0,0);
    58         rmq(dis,mxx,1),rmq(dis,mii,0);
    59         while(m--)
    60         {
    61             scanf("%d",&x);
    62             printf("%d
    ",find(x));
    63         }
    64     }
    65     return 0;
    66 }
    View Code
  • 相关阅读:
    mybatis(2)操作数据库
    《构建之法》阅读笔记02
    mybatis(4)使用注解方式配置sql语句
    mybatis(5)参数传递
    Android Studio安装
    《构建之法》阅读笔记01
    反射
    mybatis(3)利用Mapper接口实现数据的增删改查
    activity组件
    mybatis(1)
  • 原文地址:https://www.cnblogs.com/bin-gege/p/6479046.html
Copyright © 2011-2022 走看看