POJ3162 线段树+DFS

来源:互联网 发布:大数据分析论文 编辑:程序博客网 时间:2024/06/03 17:18

题意:要求得到树上每点能够走到的最远距离 然后从中抽取出连续的序列 序列之间的最大值和最小值的差不能大于m

然后求这个序列最长能够有多长

解法:先利用树的直径得到每个点能走到的最远的距离一定是在两个点之一 这个反证法想一下就可以了 

假如能走到更远的点 那那个点还会是直径的一端吗

然后我们根据距离建树 建完之后双指针就可以了

那个dfs函数参考了别人 给我很大的启发 大概是代码复用只需要修改数组名就好了

#include<cstdio>#include<limits.h>#include<algorithm>using namespace std;#define maxn 1111111#define ls (rt<<1)#define rs (rt<<1|1)#define mid ((l+r)>>1)struct edge{int u,v,w,next;    edge(int  u=0,int v=0,int w=0):u(u),v(v),w(w){}}e[maxn*2];int n,m,cnt,head[maxn],d[maxn],irene[maxn],jessica[maxn],mx,mn;void init(){cnt=0;for(int i=0;i<=n;i++)head[i]=-1;}void _add(int u,int v,int w){    e[cnt]=edge(u,v,w);e[cnt].next=head[u];head[u]=cnt++;}void dfs(int u,int fa,int dis,int *d){for(int i=head[u];i!=-1;i=e[i].next){int v=e[i].v,w=e[i].w;if(v!=fa){            d[v]=dis+w;            dfs(v,u,dis+w,d);        }}}int mi[maxn<<2],ma[maxn<<2];inline void up(int rt){    ma[rt]=max(ma[ls],ma[rs]);    mi[rt]=min(mi[ls],mi[rs]);}inline void build(int rt,int l,int r){    if(l==r){        ma[rt]=mi[rt]=d[l];return ;    }    build(ls,l,mid);    build(rs,mid+1,r);    up(rt);}void query(int rt,int l,int r,int L,int R){    if(L<=l&&r<=R){        mx=max(mx,ma[rt]);mn=min(mn,mi[rt]);        return ;    }    if(L<=mid)query(ls,l,mid,L,R);    if(mid<R)query(rs,mid+1,r,L,R);}int a,b,w;int main(){while(scanf("%d%d",&n,&m)!=EOF){init();        for(int i=2;i<=n;++i){            scanf("%d%d",&a,&w);            _add(i,a,w);_add(a,i,w);        }                a=1,b=1;d[1]=0;dfs(1,-1,0,d);                for(int i=1;i<=n;i++)if(d[a]<d[i])a=i;//farest        irene[a]=0;dfs(a,-1,0,irene);        for(int i=1;i<=n;i++)if(irene[b]<irene[i])b=i;        jessica[b]=0;dfs(b,-1,0,jessica);                for(int i=1;i<=n;i++)d[i]=max(irene[i],jessica[i]);                build(1,1,n);        int st=1,ed=1,ans=0;        while(ed<=n){            mx=-INT_MAX,mn=INT_MAX;            query(1,1,n,st,ed);            if(mx-mn<=m){                ans=max(ed-st+1,ans);                ed++;            }else st++;        }printf("%d\n",ans);}return 0;}



0 0
原创粉丝点击