poj 3162 树形dp+单调队列 很好的题
2012-10-08 20:51
369 查看
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<vector> #include<sstream> #include<string> #include<climits> #include<set> #include<bitset> #include<cmath> #include<deque> #include<map> #include<queue> #define iinf 1000000000 #define linf 1000000000000000000LL #define dinf 1e200 #define all(v) (v).begin(),(v).end() #define sz(x) x.size() #define pb push_back #define mp make_pair #define lng long long #define sqr(a) ((a)*(a)) #define pii pair<int,int> #define pll pair<lng,lng> #define pss pair<string,string> #define pdd pair<double,double> #define X first #define Y second #define pi 3.14159265359 #define ff(i,xi,n) for(int i=xi;i<=(int)(n);++i) #define ffd(i,xi,n) for(int i=xi;i>=(int)(n);--i) #define ffl(i,r) for(int i=head[r];i!=-1;i=edge[i].next) #define cc(i,j) memset(i,j,sizeof(i)) #define N 1000001 #define M 1000001 using namespace std; typedef vector<int> vi; typedef vector<string> vs; typedef unsigned int uint; typedef unsigned lng ulng; template<class T> inline void checkmax(T &x,T y){if(x<y) x=y;} template<class T> inline void checkmin(T &x,T y){if(x>y) x=y;} template<class T> inline T Min(T x,T y){return (x>y?y:x);} template<class T> inline T Max(T x,T y){return (x<y?y:x);} struct pp{int v,w,next;}edge[2*M];int tot=0,head ,n,m,dp1 ,dp2 ,edp ,id ,q1 ,q2 ,r1,f1,r2,f2; inline void addedge(int u,int v,int w){edge[tot].v=v,edge[tot].w=w,edge[tot].next=head[u],head[u]=tot++;} void dfs1(int r,int pre) { dp1[r]=0,dp2[r]=0,id[r]=0; ffl(i,r) { int v=edge[i].v,w=edge[i].w; if(v==pre) continue; dfs1(v,r); if(dp1[v]+w>dp1[r]) dp2[r]=dp1[r],dp1[r]=dp1[v]+w,id[r]=v; else if(dp1[v]+w>dp2[r]) dp2[r]=dp1[v]+w; } } void dfs2(int r,int pre) { ffl(i,r) { int v=edge[i].v,w=edge[i].w; if(v==pre) continue; if(id[r]==v) edp[v]=w+dp2[r]; else edp[v]=w+dp1[r]; edp[v]=Max(edp[v],w+edp[r]); dfs2(v,r); } } int main() { #ifdef DEBUG // freopen("data.in","r",stdin); // freopen("data.out","w",stdout); #endif while(scanf("%d%d",&n,&m)==2) { tot=0;cc(head,-1);cc(edp,0); ff(i,2,n) { int v,w; scanf("%d%d",&v,&w); addedge(i,v,w); addedge(v,i,w); } dfs1(1,-1);edp[1]=0;dfs2(1,-1); ff(i,1,n){edp[i]=Max(edp[i],dp1[i]);} int ans=1; q1[0]=0;q2[0]=0;r1=1;f1=1;r2=1;f2=1;q1[1]=1;q2[1]=1;int st=1; ff(i,2,n) { int w=edp[i]; if(w>=edp[q1[f1]]-m&&w<=edp[q2[f2]]+m) { checkmax(ans,i-st+1); while(f1<=r1&&edp[q1[r1]]<=w) --r1; q1[++r1]=i; while(f2<=r2&&edp[q2[r2]]>=w) --r2; q2[++r2]=i; } else if(w<edp[q1[f1]]-m) { while(f1<=r1&&edp[q1[f1]]-w>m) ++f1; st=q1[f1-1]+1; checkmax(ans,i-st+1); while(f1<=r1&&edp[q1[r1]]<=w) --r1; q1[++r1]=i; while(f2<=r2&&edp[q2[r2]]>=w) --r2; q2[++r2]=i; } else { while(f2<=r2&&edp[q2[f2]]+m<w) ++f2; st=q2[f2-1]+1; checkmax(ans,i-st+1); while(f1<=r1&&edp[q1[r1]]<=w) --r1; q1[++r1]=i; while(f2<=r2&&edp[q2[r2]]>=w) --r2; q2[++r2]=i; } } printf("%d\n",ans); } return 0; } /* made by qinggege */
相关文章推荐
- POJ 3162 Walking Race(树形dp+单调队列 or 线段树)
- 【POJ 3162】 Walking Race (树形DP-求树上最长路径问题,+单调队列)
- POJ 3162 Walking Race(树形DP+单调队列)
- POJ 3162 Walking Race(树形DP + 单调队列)
- poj 3162 Walking Race 树形dp + 单调队列
- POJ - 4003 Bob’s Race (树形DP+二分+单调队列+记忆化搜索)@
- poj 3162 树DP+单调队列
- POJ3162 Walking Race(树形DP+尺取法+单调队列)
- POJ 3017 Cut the Sequence (单调队列优化DP)
- poj 3017 Cut the Sequence(DP+单调队列)
- poj 1821(单调队列优化dp)
- POJ 3162 Walking Race 树形DP
- POJ 2823 Sliding Window 单调队列优化DP
- poj 3017 Cut the Sequence(DP+单调队列+set)
- 【树形DP】Poj 3162 Walking Race (DP_树形DP(线段树))
- poj 3162 Walking Race (dfs+尺取法单调队列)★
- UVaLive 4327 | POJ 3926 - Parade (单调队列优化DP)
- Poj 3017 Cut the Sequence (DP,单调队列优化,数据结构优化)
- 幸福的道路_bzoj2500_树形dp+单调队列
- POJ 3162 Walking Race 树的直径+单调队列(其实暴力也可以>_<)