POJ-3162(树形DP+单调队列)
题意:求1~n 在树上的最远距离d[i] , 1<=i<=n; 然后求出d数组里最长区间长度且满足区间最大值-最小值<=m;
思路:树形dp求出数组d; 然后两个单调队列分别维护最小值最大值,并且维护一个最左端点l,更新队列 、端点和答案即可。
AC代码
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=1e6+5;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
#define ls (i<<1)
#define rs (i<<1|1)
#define fi first
#define se second
#define mk make_pair
#define mem(a,b) memset(a,b,sizeof(a))
LL read()
{
LL x=0,t=1;
char ch=getchar();
while(!isdigit(ch)){ if(ch=='-')t=-1; ch=getchar(); }
while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
return x*t;
}
struct edge
{
int from,to,w,next;
edge(){}
edge(int ff,int tt,int ww,int nn)
{
from=ff; to=tt; w=ww; next=nn;
}
};
edge e[N<<1];
LL f[N],g[N];
int p[N],head[N],tot,n,m;
pair<LL,int> qmax[N],qmin[N];
void add(int from,int to,int w)
{
e[++tot]=edge(from,to,w,head[from]);
head[from]=tot;
}
void dfs(int u,int pre)
{
f[u]=0;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(v==pre) continue;
dfs(v,p[v]=u);
f[u]=max(f[v]+e[i].w,f[u]);
}
}
void dfs2(int u,int pre)
{
g[u]=g[pre];
int tmp=0;
for(int i=head[pre];i;i=e[i].next)
{
int v=e[i].to;
if(v==p[pre]) continue;
if(v==u) tmp=e[i].w;
else g[u]=max(g[u],f[v]+e[i].w);
}
g[u]+=tmp;
for(int i=head[u];i;i=e[i].next)
if(e[i].to!=pre) dfs2(e[i].to,u);
}
void init()
{
memset(head,0,sizeof(int)*(n+1) );
tot=0;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
for(int i=2;i<=n;i++)
{
int x=read(),y=read();
add(i,x,y); add(x,i,y);
}
dfs(1,0);
dfs2(1,0);
int ans=0,l=1;
int h1=1,h2=1,t1=0,t2=0;
for(int i=1;i<=n;i++)
{
LL tmp=max(f[i],g[i]);
while(h1<=t1&&qmax[t1].fi<tmp) t1--;
while(h2<=t2&&qmin[t2].fi>tmp) t2--;
qmax[++t1]=mk(tmp,i); qmin[++t2]=mk(tmp,i);
while(h1<=t1&&h2<=t2&&qmax[h1].fi-qmin[h2].fi>m)
{
if(qmax[h1].se>qmin[h2].se)
l=qmin[h2++].se+1;
else
l=qmax[h1++].se+1;
}
ans=max(ans,i-l+1);
}
printf("%d\n",ans);
}
}
WA代码(不知道哪里错了,反正重写就过了,改日再找)
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=1e6+5;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
#define ls (i<<1)
#define rs (i<<1|1)
#define fi first
#define se second
#define mk make_pair
#define mem(a,b) memset(a,b,sizeof(a))
LL read()
{
LL x=0,t=1;
char ch=getchar();
while(!isdigit(ch)){ if(ch=='-')t=-1; ch=getchar(); }
while(isdigit(ch)){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*t;
}
struct edge
{
int from,to,next;
LL w;
edge(){}
edge(int ff,int tt,LL ww,int nn)
{
from=ff; to=tt; w=ww; next=nn;
}
};
edge e[N<<1];
int head[N],tot;
LL f[N],g[N],p[N];
pair<LL,LL> qmax[N],qmin[N];
void add(int from,int to,LL w)
{
e[++tot]=edge(from,to,w,head[from]);
head[from]=tot;
}
void dfs(int u,int pre)
{
f[u]=0;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(v==pre) continue;
dfs(v,p[v]=u);
//printf("%d -> %d ,%lld\n",u,v,e[i].w);
f[u]=max(f[u],f[v]+e[i].w);
}
// printf("f[%d]=%d\n",u,f[u]);
}
void dfs2(int u,int pre)
{
g[u]=g[pre];
int tmp=0;
for(int i=head[pre];i;i=e[i].next)
{
int v=e[i].to;
if(v==p[pre]) continue;
if(v==u) tmp=e[i].w;
else g[u]=max(g[u],f[v]+e[i].w);
}
g[u]+=tmp;
// printf("%d %lld\n",u,g[u]);
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(v==pre) continue;
dfs2(v,u);
//printf("...\n");
}
}
void init(int n)
{
memset(head,0,sizeof(int)*(n+1));
tot=0;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
init(n);
for(int i=2;i<=n;i++)
{
LL x=read(),y=read();
add(i,x,y); add(x,i,y);
}
dfs(1,0);
dfs2(1,0);
LL h1=1,h2=1,t1=0,t2=0;
LL l=1,ans=0;
for(int i=1;i<=n;i++)
{
LL tmp=max(f[i],g[i]); //printf("%lld%c",tmp,i==n?'\n':' ');
while(h1<=t1&&qmax[h1].se<tmp) t1--;
while(h2<=t2&&qmin[h2].se>tmp) t2--;
qmax[++t1]=mk(i,tmp); qmin[++t2]=mk(i,tmp);//printf("h1=%d h2=%d t1=%d t2=%d\n",h1,h2,t1,t2);
while(h1<=t1&&h2<=t2&&qmax[h1].se-qmin[h2].se>m)
{
if(qmax[h1].fi>qmin[h2].fi)
l=qmin[h2++].fi+1;
else l=qmax[h1++].fi+1;
}
ans=max(ans,i+1-l);
}
printf("%lld\n",ans);
}
return 0;
}
/*
4 3
1 4
1 2
2 2
*/
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步