点分治 [IOI2011]Race

BZOJ2599.

放板子。利用agc009-D 代码简洁了很多

 1 #include <bits/stdc++.h>
 2 #define N 200005
 3 using namespace std;
 4 int n,m,K,F[N][30],H[N],x,y,z,h[N],f[1000005],T,O,e[N],ans,d[N],g[N],t;
 5 vector <int> a[N],b[N];
 6 void QH(int x,int fa){
 7     int y,z=-1;
 8     for (int i=0;i<a[x].size();++i)
 9     if (a[x][i]!=fa){
10         QH(y=a[x][i],x);
11         for (int j=0;j<30;++j){
12             if (F[y][j]&F[x][j]) z=max(z,j);
13             F[x][j]|=F[y][j];
14         }
15     }
16     for (++z;F[x][z];++z);
17     F[x][z]=1; H[x]=z;
18     for (--z;~z;--z) F[x][z]=0;
19 }
20 void dfs(int x,int y,int o){
21     if (h[x]>K) return;
22     d[++t]=h[x]; g[t]=o; e[++T]=x;
23     ans=min(ans,f[K-h[x]]+o);
24     for (int i=0;i<a[x].size();++i)
25     if (H[a[x][i]]<O&&a[x][i]!=y){
26         h[a[x][i]]=h[x]+b[x][i];
27         dfs(a[x][i],x,o+1);
28     }
29 }
30 void go(int x){
31     O=H[x]; h[x]=T=0;
32     for (int i=0;i<a[x].size();++i)
33     if (H[a[x][i]]<O){
34         h[a[x][i]]=h[x]+b[x][i];
35         t=0; dfs(a[x][i],x,1);
36         for (int j=1;j<=t;++j) f[d[j]]=min(f[d[j]],g[j]);
37     }
38     for (int i=1;i<=T;++i) f[h[e[i]]]=n+5;
39 }
40 int main(){
41     scanf("%d%d",&n,&K);
42     for (int i=1;i<n;++i){
43         scanf("%d%d%d",&x,&y,&z);
44         ++x; ++y;
45         a[x].push_back(y);
46         b[x].push_back(z);
47         a[y].push_back(x);
48         b[y].push_back(z);
49     }
50     QH(1,0); ans=n+5;
51     for (int i=1;i<=K;++i) f[i]=n+5;
52     for (int i=1;i<=n;++i) go(i);
53     printf("%d\n",ans>n?-1:ans);
54     return 0;
55 }
云流

 

posted @ 2017-11-20 13:42  cyz666  阅读(154)  评论(0编辑  收藏