Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1994 Accepted Submission(s): 619
首先是两遍dfs,预处理出每个结点到叶子结点的巨大距离。
然后使用rmq来查询区间的最大最小值。
每次查询扫描一遍就可以了、
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-8 16:56:11 4 File Name :E:\2013ACM\专题强化训练\区域赛\2011福州\C.cpp 5 ************************************************ */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 const int MAXN = 50010; 21 struct Edge 22 { 23 int to,next; 24 int w; 25 }edge[MAXN*2]; 26 int head[MAXN],tot; 27 void init() 28 { 29 tot = 0; 30 memset(head,-1,sizeof(head)); 31 } 32 void addedge(int u,int v,int w) 33 { 34 edge[tot].to = v; 35 edge[tot].w = w; 36 edge[tot].next = head[u]; 37 head[u] = tot++; 38 } 39 int maxn[MAXN],smaxn[MAXN]; 40 int maxid[MAXN],smaxid[MAXN]; 41 void dfs1(int u,int pre) 42 { 43 maxn[u] = smaxn[u] = maxid[u] = smaxid[u] = 0; 44 for(int i = head[u];i != -1;i = edge[i].next) 45 { 46 int v = edge[i].to; 47 if(pre == v)continue; 48 dfs1(v,u); 49 if(maxn[v] + edge[i].w > smaxn[u]) 50 { 51 smaxid[u] = v; 52 smaxn[u] = maxn[v] + edge[i].w; 53 if(maxn[u] < smaxn[u]) 54 { 55 swap(maxn[u],smaxn[u]); 56 swap(maxid[u],smaxid[u]); 57 } 58 } 59 } 60 } 61 void dfs2(int u,int pre) 62 { 63 for(int i = head[u];i != -1;i = edge[i].next) 64 { 65 int v = edge[i].to; 66 if(pre == v)continue; 67 if(maxid[u] == v) 68 { 69 if(smaxn[u] + edge[i].w > smaxn[v]) 70 { 71 smaxn[v] = smaxn[u] + edge[i].w; 72 smaxid[v] = u; 73 if(maxn[v] < smaxn[v]) 74 { 75 swap(maxn[v],smaxn[v]); 76 swap(maxid[v],smaxid[v]); 77 } 78 } 79 } 80 else 81 { 82 if(maxn[u] + edge[i].w > smaxn[v]) 83 { 84 smaxn[v] = maxn[u] + edge[i].w; 85 smaxid[v] = u; 86 if(maxn[v] < smaxn[v]) 87 { 88 swap(maxn[v],smaxn[v]); 89 swap(maxid[v],smaxid[v]); 90 } 91 } 92 } 93 dfs2(v,u); 94 } 95 } 96 int a[MAXN]; 97 98 int dp1[MAXN][20]; 99 int dp2[MAXN][20]; 100 int mm[MAXN]; 101 void initRMQ(int n) 102 { 103 mm[0] = -1; 104 for(int i = 1;i <= n;i++) 105 { 106 mm[i] = ((i&(i-1)) == 0)?mm[i-1]+1:mm[i-1]; 107 dp1[i][0] = a[i]; 108 dp2[i][0] = a[i]; 109 } 110 for(int j = 1;j <= mm[n];j++) 111 for(int i = 1;i + (1<<j) - 1 <= n;i++) 112 { 113 dp1[i][j] = max(dp1[i][j-1],dp1[i + (1<<(j-1))][j-1]); 114 dp2[i][j] = min(dp2[i][j-1],dp2[i + (1<<(j-1))][j-1]); 115 } 116 } 117 int rmq(int x,int y) 118 { 119 int k = mm[y-x+1]; 120 return max(dp1[x][k],dp1[y-(1<<k)+1][k]) - min(dp2[x][k],dp2[y-(1<<k)+1][k]); 121 } 122 int main() 123 { 124 //freopen("in.txt","r",stdin); 125 //freopen("out.txt","w",stdout); 126 int n,m; 127 int u,v,w; 128 int Q; 129 while(scanf("%d%d",&n,&m) == 2) 130 { 131 if(n == 0 && m == 0)break; 132 init(); 133 for(int i = 1;i < n;i++) 134 { 135 scanf("%d%d%d",&u,&v,&w); 136 addedge(u,v,w); 137 addedge(v,u,w); 138 } 139 dfs1(1,1); 140 dfs2(1,1); 141 for(int i = 1;i <= n;i++) 142 a[i] = maxn[i]; 143 initRMQ(n); 144 while(m--) 145 { 146 scanf("%d",&Q); 147 int ans = 0; 148 int id = 1; 149 for(int i = 1;i <= n;i++) 150 { 151 while(id <= i && rmq(id,i) > Q)id++; 152 ans = max(ans,i-id+1); 153 } 154 printf("%d\n",ans); 155 } 156 } 157 return 0; 158 }