2011 Asia Fuzhou Regional Contest C题 Bob’s Race hdu 4123&&poj 4003

题意:给你一颗树,得到每个节点可到达的最远路径长度组成的序列,每给定一个q,求最长满足{最大值-最小值<=q}的连续序列

思路:

 1,树形DP得到序列

    1.1 DFS 得到每个节点在其子树中“最大距离”以及“次大距离”<这里的最大距离和次大距离是说如果最大距离经历子节点a,那么次大距离就是不通过子节点a的最大距离,而不是除去最大距离的最大距离,这个地方就是求解最大距离的关键>;

    1.2 DP求得每个节点通过其父节点的最大距离,更新最大距离;

   2,单队列求最长序列

    求最长序列是基于:求区间内最大,最小值以及决策单调性,可以用rmq甚至线段树

 

View Code
  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <vector>
  4 #define MAXN 50010
  5 #define pb push_back
  6 using namespace std;
  7 vector<int>nodes[MAXN];
  8 int n,d[MAXN];
  9 struct Node{
 10     int v,p;
 11 }quea[MAXN],quei[MAXN];
 12 struct Nod{
 13     int max[2],id[2];
 14 }mm[MAXN];
 15 void DFS(int rt,int f)
 16 {
 17     int i,j,num=nodes[rt].size();
 18     mm[rt].max[0]=mm[rt].max[1]=0;
 19     mm[rt].id[0]=mm[rt].id[1]=-1;
 20     for(i=0;i<num;i+=2)
 21     {
 22         j=nodes[rt][i];
 23         if(j!=f)
 24         {
 25             DFS(j,rt);
 26             if(mm[rt].max[1]<mm[j].max[0]+nodes[rt][i+1])
 27             {
 28                 if(mm[rt].max[0]<mm[j].max[0]+nodes[rt][i+1])
 29                     mm[rt].max[1]=mm[rt].max[0],mm[rt].id[1]=mm[rt].id[0],mm[rt].max[0]=mm[j].max[0]+nodes[rt][i+1],mm[rt].id[0]=j;
 30                 else
 31                     mm[rt].max[1]=mm[j].max[0]+nodes[rt][i+1],mm[rt].id[1]=j;
 32             }
 33         }
 34     }
 35 }
 36 void DP(int rt,int f,int v)
 37 {
 38     int temp;
 39     if(rt!=1)
 40     {
 41         if(mm[f].id[0]!=rt)
 42         {
 43             temp=mm[f].max[0]+v;
 44             if(mm[rt].max[1]<temp)
 45             {
 46                 if(mm[rt].max[0]<temp)
 47                    mm[rt].id[1]=mm[rt].id[0],mm[rt].max[1]=mm[rt].max[0],mm[rt].max[0]=temp,mm[rt].id[0]=f;
 48                 else
 49                     mm[rt].max[1]=temp,mm[rt].id[1]=f;
 50             }
 51         }
 52         else{
 53             temp=mm[f].max[1]+v;
 54             if(mm[rt].max[1]<temp)
 55             {
 56                 if(mm[rt].max[0]<temp)
 57                     mm[rt].id[1]=mm[rt].id[0],mm[rt].max[1]=mm[rt].max[0],mm[rt].max[0]=temp,mm[rt].id[0]=f;
 58                 else
 59                     mm[rt].max[1]=temp,mm[rt].id[1]=f;
 60             }
 61         }
 62     }
 63     if(mm[rt].max[0]<mm[rt].max[1])
 64     {
 65         temp=mm[rt].max[0],mm[rt].max[0]=mm[rt].max[1],mm[rt].max[1]=temp;
 66         temp=mm[rt].id[0],mm[rt].id[0]=mm[rt].id[1],mm[rt].id[1]=temp;
 67     }
 68     int i,j,num=nodes[rt].size();
 69     for(i=0;i<num;i+=2)
 70     {
 71         j=nodes[rt][i];
 72         if(j!=f)
 73             DP(j,rt,nodes[rt][i+1]);
 74     }
 75 }
 76 void Query(int q)
 77 {
 78     int ha,ta,hi,ti,i,p=1,ans=0;
 79     ha=ta=hi=ti=0;
 80     quei[ti].v=d[1],quei[ti++].p=1;
 81     quea[ta++]=quei[ti-1];
 82 
 83     for(i=1;i<=n;i++)
 84     {
 85         while(ha<ta&&quea[ta-1].v<=d[i])
 86             ta--;
 87         quea[ta].p=i,quea[ta++].v=d[i];
 88         while(hi<ti&&quei[ti-1].v>=d[i])
 89             ti--;
 90         quei[ti].p=i,quei[ti++].v=d[i];
 91 
 92         while(quea[ha].v-quei[hi].v>q)
 93         {
 94             if(quea[ha].p>quei[hi].p)
 95             {
 96                 p=quei[hi].p+1;
 97                 hi++;
 98             }
 99             else{
100                 p=quea[ha].p+1;
101                 ha++;
102             }
103         }
104         if(quea[ha].v-quei[hi].v<=q&&ans<i-p+1)
105             ans=i-p+1;
106     }
107     printf("%d\n",ans);
108 }
109 int main()
110 {
111     int m,i,j,a,b,c,q;
112     while(scanf("%d%d",&n,&m)!=EOF)
113     {
114         if(n==0&&m==0)
115             break;
116         for(i=0;i<=n;i++)
117             nodes[i].clear();
118 
119         for(i=1;i<n;i++)
120         {
121             scanf("%d%d%d",&a,&b,&c);
122             nodes[a].pb(b);
123             nodes[a].pb(c);
124             nodes[b].pb(a);
125             nodes[b].pb(c);
126         }
127         DFS(1,0);
128 
129         DP(1,0,0);
130         for(i=1;i<=n;i++)
131             d[i]=max(mm[i].max[0],mm[i].max[1]);
132         while(m--)
133         {
134             scanf("%d",&q);
135             Query(q);
136         }
137     }
138     return 0;
139 }

 

 

posted on 2012-07-27 18:06  sleeper_qp  阅读(368)  评论(1编辑  收藏  举报

导航