P4149 [IOI2011]Race
对于这道题,明显是点分治,权值等于k,可以用桶统计树上路径(但注意要清空);
对于每颗子树,先与之前的子树拼k,再更新桶,维护t["len"]最小边数;
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define up(i,l,r) for(register int i = (l); i <= (r); ++i) 4 #define dn(i,l,r) for(register int i = (l); i >= (r); --i) 5 #define ll long long 6 #define re register 7 using namespace std; 8 template <typename T> void in(T &x) { 9 x = 0; T f = 1; char ch = getchar(); 10 while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();} 11 while( isdigit(ch)) {x = 10 * x + ch - 48; ch = getchar();} 12 x *= f; 13 } 14 template <typename T> void out(T x) { 15 if(x < 0) x = -x , putchar('-'); 16 if(x > 9) out(x/10); 17 putchar(x%10 + 48); 18 } 19 //--------------------------------------------------------- 20 const int N = 2e5+7,inf = 1e9+7; 21 int n,k; 22 23 struct edge { 24 int v,w,nxt; 25 }e[N<<1]; int tot,head[N]; 26 27 void add(int u,int v,int w) { 28 e[++tot].v = v; e[tot].w = w,e[tot].nxt = head[u]; head[u] = tot; 29 } 30 31 int Tsize,rt; 32 int f[N],size[N]; 33 int dis[N],dep[N]; 34 35 int t[1000007]; 36 37 bool vis[N]; 38 int ans = inf; 39 40 void get_rt(int u,int fa) { 41 size[u] = 1; f[u] = 0; 42 for(int i = head[u]; i ;i = e[i].nxt) { 43 int v = e[i].v; if(v == fa || vis[v]) continue; 44 get_rt(v,u); size[u] += size[v]; 45 //if(f[u] < size[v]) f[u] = size[v]; 46 f[u] = max(f[u],size[v]); 47 } 48 f[u] = max(f[u],Tsize-size[u]); 49 if(f[u] < f[rt]) rt = u; 50 } 51 52 void get_ans(int u,int fa) { 53 //if(dis[u] > k) return;//> 54 if(dis[u] <= k) 55 ans = min(ans,t[k-dis[u]]+dep[u]); 56 for(int i = head[u]; i;i = e[i].nxt) { 57 int v = e[i].v; if(v == fa || vis[v]) continue; 58 dis[v] = dis[u] + e[i].w; dep[v] = dep[u] + 1; 59 get_ans(v,u); //!!!!!未写 60 } 61 } 62 63 void update_t(int u,int fa,bool flag) { 64 //if(dis[u] > k) return;//> 65 if(dis[u] <= k) { 66 if(flag) t[dis[u]] = min(t[dis[u]],dep[u]); 67 else t[dis[u]] = inf; 68 } 69 for(int i = head[u]; i ;i = e[i].nxt) { 70 int v = e[i].v; if(v == fa || vis[v]) continue; 71 update_t(v,u,flag); 72 } 73 } 74 75 void solve(int u) { 76 vis[u] = 1; t[0] = 0; //dep[u] = 0; 77 for(int i = head[u]; i; i = e[i].nxt) { 78 int v = e[i].v; if(vis[v]) continue; 79 dep[v] = 1,dis[v] = e[i].w; get_ans(v,0); update_t(v,0,1); 80 } 81 for(int i = head[u]; i; i = e[i].nxt) { 82 int v = e[i].v; if(vis[v]) continue; 83 update_t(v,0,0); 84 } 85 for(int i = head[u]; i ; i = e[i].nxt) { 86 int v = e[i].v; if(vis[v]) continue; 87 Tsize = size[v],rt = 0; get_rt(v,0); solve(rt); 88 //rt - > v 89 } 90 } 91 92 int main() { 93 in(n); in(k); int x,y,w; 94 up(i,1,n-1) in(x),in(y),in(w),add(x+1,y+1,w),add(y+1,x+1,w); 95 up(i,0,k) t[i] = inf; 96 Tsize = n,rt = 0,f[0] = n+1; get_rt(1,0); solve(rt); 97 if(ans != inf) out(ans); else out(-1); 98 return 0; 99 }