BZOJ 2599 [IOI2011]Race (点分治)
题目大意:
求树上长度为K的路径里,边数的最小值,$n<=10^{5}$
树分治入门题= =
为了防止出现不合法的路径进入统计,在每次选择的重心周围的节点进行统计
开一个桶,记录当前长度的路径下,边数的最小值
每次枚举当前子树内每个节点,用桶内的信息更新答案
枚举完当前子树内所有的节点之后,再把这些节点的信息推入桶内
这样就能防止出现走重边的情况了
1 #include <cmath> 2 #include <vector> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #define N1 200010 7 #define M1 1000010 8 #define ll long long 9 #define inf 0x3f3f3f3f 10 using namespace std; 11 12 int gint() 13 { 14 int ret=0,fh=1;char c=getchar(); 15 while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} 16 while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();} 17 return ret*fh; 18 } 19 int n,K; 20 struct Edge{ 21 int to[N1<<1],nxt[N1<<1],val[N1<<1],head[N1],cte; 22 void ae(int u,int v,int w) 23 { 24 cte++;to[cte]=v,val[cte]=w; 25 nxt[cte]=head[u],head[u]=cte; 26 } 27 }e; 28 int ms[N1],sz[N1],use[N1],tsz,G; 29 void gra(int u,int dad) 30 { 31 sz[u]=1; ms[u]=0; 32 for(int j=e.head[u];j;j=e.nxt[j]) 33 { 34 if(e.to[j]==dad||use[e.to[j]]) continue; 35 gra(e.to[j],u); 36 sz[u]+=sz[e.to[j]]; ms[u]=max(ms[u],sz[e.to[j]]); 37 } 38 ms[u]=max(ms[u],tsz-sz[u]); 39 if(ms[u]<ms[G]) G=u; 40 } 41 int dep[N1],dis[N1],lim; 42 int q[N1],eq,tq[N1],et; 43 void dfs_push(int u,int dad) 44 { 45 if(dis[u]>K) return; 46 tq[++et]=u; 47 for(int j=e.head[u];j;j=e.nxt[j]) 48 { 49 if(e.to[j]==dad||use[e.to[j]]) continue; 50 dep[e.to[j]]=dep[u]+1; dis[e.to[j]]=dis[u]+e.val[j]; 51 dfs_push(e.to[j],u); 52 } 53 } 54 int mi[M1],ans; 55 int calc(int u) 56 { 57 int i,j,x,v; 58 mi[0]=0; 59 for(j=e.head[u];j;j=e.nxt[j]) 60 { 61 v=e.to[j]; if(use[v]) continue; 62 dis[v]=e.val[j]; dep[v]=1; dfs_push(v,u); 63 for(i=1;i<=et;i++) 64 { 65 x=tq[i]; 66 ans=min(ans,dep[x]+mi[K-dis[x]]); 67 } 68 while(et) 69 { 70 x=tq[et--]; q[++eq]=dis[x]; 71 mi[dis[x]]=min(mi[dis[x]],dep[x]); 72 } 73 } 74 while(eq) { x=q[eq--]; mi[x]=inf; } 75 } 76 void main_dfs(int u) 77 { 78 use[u]=1; calc(u); 79 for(int j=e.head[u];j;j=e.nxt[j]) 80 { 81 if(use[e.to[j]]) continue; 82 G=0; tsz=sz[e.to[j]]; gra(e.to[j],u); 83 main_dfs(G); 84 } 85 } 86 void init() 87 { 88 memset(mi,0x3f,sizeof(mi)); 89 ans=inf; 90 } 91 92 int main() 93 { 94 //freopen("t2.in","r",stdin); 95 int i,x,y,z; init(); 96 scanf("%d%d",&n,&K); 97 for(i=1;i<n;i++) 98 { 99 x=gint(),y=gint(),z=gint(); x++,y++; 100 e.ae(x,y,z),e.ae(y,x,z); 101 } 102 ms[0]=tsz=n; G=0; gra(1,-1); gra(G,-1); 103 main_dfs(G); 104 if(ans==inf) puts("-1"); 105 else printf("%d\n",ans); 106 return 0; 107 }