HDU 4123(树上任意点到其他点的最远距离,rmq

题目:求出一棵树上任意一点能到的最远距离,然后若干询问,问区间内最大最小距离只差小于q的区间最长有多长。

思路:最远距离通过两次dfs树形dp求得,询问需要先用st表处理一下,然后线性扫。基本是参考kuangbin的。

ps:可能是我写挫了。。用vector做邻接表是1996ms过了一次,然后就是无限tle。。。。不得不改成手写链表才搞到1500ms。。。vector感觉不能随便用了啊。。。。。。

http://www.cnblogs.com/kuangbin/archive/2013/11/08/3414812.html

#include <iostream>
#include <map>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <set>
#include <cmath>
#define pb push_back
#define fs first
#define se second
#define sq(x) (x)*(x)
#define eps 0.0000000001
#define IINF (1<<30)
#define clr(x) memset((x),0,sizeof (x))
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
const int maxv=5e4+300;
int N,M;
struct EDGE{
    int t,d;
    EDGE *nt;
}pool[maxv*3];
int ph=0;
EDGE *newedge(){
    pool[ph].nt=NULL;
    return &pool[ph++];
}
EDGE *head[maxv],*tail[maxv];
int maxd[maxv],maxdn[maxv],smaxd[maxv],smaxdn[maxv];
void addedge(int x,int y,int z){
    tail[x]->nt=newedge();
    tail[x]=tail[x]->nt;
    tail[x]->t=y,tail[x]->d=z;
}
void dfs1(int v,int fa){
    for(EDGE *i=head[v]->nt;i!=NULL;i=i->nt){
        int u=i->t;
        int len=i->d;
        if(u==fa) continue;
        dfs1(u,v);
        if(maxd[u]+len>smaxd[v]){
            smaxd[v]=maxd[u]+len;
            smaxdn[v]=u;
            if(smaxd[v]>maxd[v]){
                swap(smaxd[v],maxd[v]);
                swap(smaxdn[v],maxdn[v]);
            }
        }
    }
}
void dfs2(int v,int fa){
    for(EDGE *i=head[v]->nt;i!=NULL;i=i->nt){
        int u=i->t;
        int len=i->d;
        if(u==fa) continue;
        if(u==maxdn[v]){
            if(smaxd[v]+len>smaxd[u]){
                smaxd[u]=smaxd[v]+len;
                smaxdn[u]=v;
                if(smaxd[u]>maxd[u]){
                    swap(smaxd[u],maxd[u]);
                    swap(smaxdn[u],maxdn[u]);
                }
            }
        }else{
            if(maxd[v]+len>smaxd[u]){
                smaxd[u]=maxd[v]+len;
                smaxdn[u]=v;
                if(smaxd[u]>maxd[u]){
                    swap(smaxd[u],maxd[u]);
                    swap(smaxdn[u],maxdn[u]);
                }
            }
        }
        dfs2(u,v);
    }
}
ll STmin[maxv][30];
ll STmax[maxv][30];
void makeST(){
    memset(STmin,0x3f,sizeof STmin);
    memset(STmax,0,sizeof STmax);
    for(int i=1;i<=N;i++){
        STmin[i][0]=STmax[i][0]=maxd[i];
    }
    for(int k=1;k<25;k++){
        for(int i=1;i+(1<<k)<=N+1;i++){
            STmin[i][k]=min(STmin[i][k-1],STmin[i+(1<<(k-1))][k-1]);
            STmax[i][k]=max(STmax[i][k-1],STmax[i+(1<<(k-1))][k-1]);
        }
    }
}
int getdif(int l,int r){
    int k=0;
    while((1<<(k+1))<r-l) k++;
    return max(STmax[l][k],STmax[r-(1<<k)][k])-min(STmin[l][k],STmin[r-(1<<k)][k]);
}
void work(){
    clr(maxd);clr(maxdn);clr(smaxd);clr(smaxdn);
    dfs1(1,0);
    dfs2(1,0);
    makeST();
    while(M--){
        int Q;
        scanf("%d",&Q);
        int ans=0;
        int j=1;
        for(int i=1;i<=N;i++){
            while(j<=N&&getdif(i,j+1)<=Q){
                j++;
            }
            ans=max(ans,j-i);
        }
        printf("%d\n",ans);
    }

}
void init(){
    ph=0;
    for(int i=0;i<=N;i++){
        head[i]=newedge();
        head[i]->nt=NULL;
        tail[i]=head[i];
    }
}
int main(){
    freopen("/home/files/CppFiles/in","r",stdin);
    /*    std::ios::sync_with_stdio(false);
        std::cin.tie(0);*/
    while(cin>>N>>M){
        if(N==0&&M==0) break;
        init();
        for(int i=0;i<N-1;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            addedge(x,y,z);
            addedge(y,x,z);
        }
        work();
    }
    return 0;
}

时间: 2024-12-29 23:28:20

HDU 4123(树上任意点到其他点的最远距离,rmq的相关文章

hdu 4123 Bob’s Race (树的直径相关+rmq+单调队列思想)

Bob's Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2115    Accepted Submission(s): 658 Problem Description Bob wants to hold a race to encourage people to do sports. He has got trouble

HDU 4123 Bob&#39;s Race:单调队列 + st表

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4123 题意: 给你一棵树,n个节点,每条边有长度. 然后有m个询问,每个询问给定一个q值. 设dis[i]为:从节点i出发,不重复经过节点,所能够走的最远距离. 每次询问问你:区间[l,r]最长能有多长,同时保证 max{dis[i]} - min{dis[i]} <= q (i∈[l,r]) 题解: 首先有一个结论: 从树上的任意一个节点出发,尽可能往远走,最终一定会到达树的直径的两个端点之一.

HDU 2196 求树上所有点能到达的最远距离

其实我不是想做这道题的...只是今天考试考了一道类似的题...然后我挂了... 但是乱搞一下还是有80分....可惜没想到正解啊! 所以今天的考试题是: 巡访 (path.pas/c/cpp) Chanxer终于当上了“中华农民联盟”的盟主,他举目四望,决定四处走走,巡视自己的农土. “中华农民联盟”的成员有个村庄,在“村村通”计划中,村庄们被条道路联通了起来,Chanxer计划从某个村庄出发,访问所有的村庄. 可是Chanxer出行有一个特殊的要求,那就是必须以农车代步,现在我们知道哪些村庄配

hdu 5416 树上的异或(思路题)

题意:给定一棵树,树上任意两点的距离为其路径上的边权的异或值,求距离等于某个值的点的对数. 思路:这道题关键是要利用异或的性质.异或最基本的一个性质是和同一个数异或两次不发生改变.而对于这道题来说求出任意两点间的距离是不现实的,但是利用异或的性质,如果我们有了每个点到根的距离,就能间接得到任意两点间的距离,对于任意两点u和v,他们之间的距离就是他们到根的距离异或起来.因为不在u到v路径上的那些边权(即lca(u,v)到根的路径上的边)被异或了两次等于没算,想到这一点就好做了,我们只要借助hash

hdu 4123 树形DP+RMQ

http://acm.hdu.edu.cn/showproblem.php?pid=4123 Problem Description Bob wants to hold a race to encourage people to do sports. He has got trouble in choosing the route. There are N houses and N - 1 roads in his village. Each road connects two houses,

HDU 4123 Bob’s Race(RMQ)

题意是说给出一棵树,N(10^5)个顶点,以及每条边的权值,现在需要选择连续的K个点(顶点编号连续),可以被选出来的条件是: 若d[i]代表顶点i到树上其他点的距离的最大值,使得区间[a, b]的d值的最大差值不大于Q, 也就是max(d[a], d[a + 1], ..., d[b]) - max(d[a], d[a + 1], ..., d[b]) <= Q Q是给出的一个查询(共有m<=500个查询),求对应每一个查询的K的最大值 思路是首先预处理出每个点到其他点的最大距离, 这可以通过

hdu 4123 Bob’s Race(树形dp+RMQ)

题目链接:hdu 4123 Bob's Race 题目大意:一个城镇有N个住户,N-1条路连接两个住户,保证N个住户联通,M次询问,给定N条边的信息,包括连 接的住户序号以及路的长度.然后是M次询问,每次询问Q,要求找到最长的连续序号,使得Max(dis[i]) - Min(dis[i]) ≤ Q(l≤i≤r),输出最大的r-l+1.dis[i]为从第i个住户出发,不重复走过路能移动的最远距离. 解题思路:树形dp,通过两次dfs,第1次处理出每个节点中孩子节点移动的最长距离和第二长距离,第2次

hdu--2196--树上某点到其余结点的最远距离

这题 很多人都是用树形dp进行2次dfs做的... 我看了他们的解题报告 并没有完全搞懂=-= 我太白痴了 伤.. 这边 我的解法 利用了一个很重要的性质---树的直径--树上任意两点间的最远距离 而同时 将这个直径上的两点x , y确定后 那么 整个树上结点的dist[ i ]也就可以确定了 max( dist[i][x] , dist[i][y] ) 要么是到x的距离 要么是到y的距离 至于 怎么找出这个直径呢? 这也是个要记住的地方 我们可以任意确定一个根结点开始bfs 得到距离它最远的结

HDU 4123 Bob’s Race

Bob’s Race Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4123 Description Bob wants to hold a race to encourage people to do sports. He has got trouble in choosing the route. There are N houses and N - 1 roads