差点放弃,竟然是自己的思路是对的,但因为一个重要的记忆优化没写在代码中超时很多次,让我很郁闷啊,还是要小心
树的最长路,怎么dfs,我写的是dfs(N,W),就是第n个节点如果走连接他的的第w号边的最长路;
为什么要求第w号边,是因为不能走重复边的原因,比如求节点a的最长路,如果他经过w号边到节点b,那么在b经过的众多边的众多最长路中,b必须不能在经过b-》a这个边了,那么就解决了重边问题;
然后得解决怎么储存的问题了,数据50000,如果开静态数组那么50000个点50000边就不行了,用点的边链表就可以解决了,不过这样代码就复杂了好多,感叹啊!!!各位大牛有什么办法,求教
然后求出了各个点的最长路,怎么求最大区间中最大值与最小值的差不超过q,我的办法是建立两个优先队列,一个最大,一个最小,那么两个优先队列的头值之差不能超过q,如果超过就把区间的头后移更新队列就可以了
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4123
我的代码: 如果需要解释,可以留言,待更新吧
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<iostream>
using namespace std;
#define Max 50001
struct list
{
int to;
int c;
int dis;
list *next;
};
struct N
{
int num;
list *next;
}adge[Max];
int head,last,que[Max],dis[Max],que1[Max],head1,last1,first;
int init(int n)
{
int i;
for(i=1;i<=n;i++)
adge[i].num=0;
memset(dis,0,sizeof(dis));
return 0;
}
int insert(int a,int b,int c)
{
list *p;
int i;
if(adge[a].num==0)
{
adge[a].next=new list;
p=adge[a].next;
}
else
{
p=adge[a].next;
for(i=1;i<adge[a].num;i++)
p=p->next;
p->next=new list;
p=p->next;
}
adge[a].num++;
p->to=b;
p->c=c;
p->dis=0;
return 0;
}
int MAX(int a,int b)
{
return a>b?a:b;
}
int MIN(int a,int b)
{
return a<b?a:b;
}
list *getlist(int x,int num)
{
if(num==1)
return adge[x].next;
list *p;
p=adge[x].next;
for(int i=1;i<num;i++)
p=p->next;
return p;
}
int getdis(int x,int w)
{
if(w==0)
return 0;
list *p,*q;
p=getlist(x,w);
if(p->dis!=0)
return p->dis;
int max=0;
for(int i=1;i<=adge[p->to].num;i++)
{
q=getlist(p->to,i);
if(q->to!=x)
{
max=MAX(getdis(p->to,i),max);
}
}
return p->dis=max+p->c;
}
int main()
{
int i,j,n,m,q,a,b,c,mm;
list *p;
while(scanf("%d%d",&n,&m)!=EOF&&!(n==0&&m==0))
{
init(n);
for(i=1;i<n;i++)
{
scanf("%d%d%d",&a,&b,&c);
insert(a,b,c);
insert(b,a,c);
}
for(i=1;i<=n;i++)
{
for(j=1;j<=adge[i].num;j++)
getdis(i,j);
}
for(i=1;i<=n;i++)
for(j=1;j<=adge[i].num;j++)
{
p=getlist(i,j);
dis[i]=MAX(dis[i],p->dis);
}
while(m--)
{
scanf("%d",&q);
head1=1;
last1=1;
que1[1]=1;
head=1;
last=1;
mm=1;
que[1]=1;
first=1;
for(i=2;i<=n;i++)
{
while(head1<=last1&&dis[i]<dis[que1[last1]])
last1--;
que1[++last1]=i;
while(head<=last&&dis[i]>dis[que[last]])
last--;
que[++last]=i;
while(dis[que[head]]-dis[que1[head1]]>q)
{
first++;
if(que1[head1]<first)
head1++;
if(que[head]<first)
head++;
}
if(i-first+1>mm)
mm=i-first+1;
}
printf("%d\n",mm);
}
}
return 0;
}