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) 编辑 收藏 举报