1. 程式人生 > >[HDU4123]Bob’s Race

[HDU4123]Bob’s Race

ctype clear 算法 line isdigit code void bsp getch

題目大意:
給定一棵$n$個點並且有邊權的樹,每個點的權值為該點能走的最遠長度,並輸入$m$個詢問,每次詢問最多有多少個編號連續的點,他們的最大最小點權差小於等於$Q$。

思路:
兩趟DP(DFS)求出每個點能走的最遠長度,然後用ST算法預處理出每一段最大最小值。
對於每組詢問,用尺取法求出最大值。
註意log2不能用cmath裏面的函數(尤其是不能在for語句上),不然會TLE,最好是自己實現。

 1 #include<cstdio>
 2 #include<cctype>
 3 #include<vector>
 4 inline int getint() {
5 char ch; 6 while(!isdigit(ch=getchar())); 7 int x=ch^0; 8 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^0); 9 return x; 10 } 11 inline int log2(const float x){ 12 return ((unsigned&)x>>23&255)-127; 13 } 14 const int N=50001,logN=16
; 15 struct Edge { 16 int to,w; 17 }; 18 std::vector<Edge> e[N]; 19 inline void add_edge(const int u,const int v,const int w) { 20 e[u].push_back((Edge){v,w}); 21 } 22 int w[N][3],son[N]; 23 void dfs1(const int x,const int par) { 24 w[x][0]=w[x][1]=0; 25 for(unsigned i=0
;i<e[x].size();i++) { 26 int &y=e[x][i].to; 27 if(y==par) continue; 28 dfs1(y,x); 29 if(w[y][0]+e[x][i].w>w[x][0]) { 30 w[x][1]=w[x][0]; 31 w[x][0]=w[y][0]+e[x][i].w; 32 son[x]=y; 33 } 34 else if(w[y][0]+e[x][i].w>w[x][1]) { 35 w[x][1]=w[y][0]+e[x][i].w; 36 } 37 } 38 } 39 void dfs2(const int x,const int par) { 40 for(unsigned i=0;i<e[x].size();i++) { 41 int &y=e[x][i].to; 42 if(y==par) continue; 43 w[y][2]=std::max(w[x][2],son[x]!=y?w[x][0]:w[x][1])+e[x][i].w; 44 dfs2(y,x); 45 } 46 } 47 int max[N][logN],min[N][logN]; 48 inline int getsum(const int l,const int r) { 49 int k=log2(r-l+1); 50 return std::max(max[l][k],max[r-(1<<k)+1][k])-std::min(min[l][k],min[r-(1<<k)+1][k]); 51 } 52 int main() { 53 for(;;) { 54 int n=getint(),m=getint(); 55 if(!n&&!m) return 0; 56 for(int i=1;i<n;i++) { 57 int u=getint(),v=getint(),w=getint(); 58 add_edge(u,v,w); 59 add_edge(v,u,w); 60 } 61 dfs1(1,0); 62 dfs2(1,0); 63 for(int i=1;i<=n;i++) { 64 max[i][0]=min[i][0]=std::max(w[i][0],w[i][2]); 65 } 66 for(int j=1;1<<j<=n;j++) { 67 for(int i=1;i<=n-(1<<j)+1;i++) { 68 max[i][j]=std::max(max[i][j-1],max[i+(1<<(j-1))][j-1]); 69 min[i][j]=std::min(min[i][j-1],min[i+(1<<(j-1))][j-1]); 70 } 71 } 72 while(m--) { 73 int q=getint(),ans=0; 74 for(int l=1,r=1;l<=r;l++) { 75 for(;r<=n&&getsum(l,r)<=q;r++); 76 ans=std::max(ans,r-l); 77 } 78 printf("%d\n",ans); 79 } 80 for(int i=1;i<=n;i++) e[i].clear(); 81 } 82 }

[HDU4123]Bob’s Race