您的位置:首页 > 其它

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
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: