1. 程式人生 > >BZOJ2599: [IOI2011]Race(點分治)

BZOJ2599: [IOI2011]Race(點分治)

Description

給一棵樹,每條邊有權.求一條簡單路徑,權值和等於K,且邊的數量最小.N <= 200000, K <= 1000000

Input

第一行 兩個整數 n, k
第二..n行 每行三個整數 表示一條無向邊的兩端和權值 (注意點的編號從0開始)

Output

一個整數 表示最小邊數量 如果不存在這樣的路徑 輸出-1

Sample Input

4 3
0 1 1
1 2 2
1 3 4

Sample Output

2

解題思路:

點分治的時候開一個桶,記錄邊權值的大小,將兩個童相加,更新最小值答案就行了。

程式碼:

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 typedef long long lnt;
  5 const int N=200010;
  6 const int maxK=1000010;
  7 struct pnt{
  8     int hd;
  9     int wgt;
 10     int dis;
 11     bool vis;
 12 }p[N];
 13 struct ent{
 14     int twd;
15 int lst; 16 int vls; 17 }e[N<<1]; 18 int n,K; 19 int cnt; 20 int ans; 21 int size; 22 int root; 23 int maxsize; 24 int has[maxK]; 25 void ade(int f,int t,int v) 26 { 27 cnt++; 28 e[cnt].twd=t; 29 e[cnt].lst=p[f].hd; 30 e[cnt].vls=v; 31 p[f].hd=cnt;
32 return ; 33 } 34 void grc_dfs(int x,int f) 35 { 36 p[x].wgt=1; 37 int maxs=-1; 38 for(int i=p[x].hd;i;i=e[i].lst) 39 { 40 int to=e[i].twd; 41 if(to==f||p[to].vis) 42 continue; 43 grc_dfs(to,x); 44 p[x].wgt+=p[to].wgt; 45 if(maxs<p[to].wgt) 46 maxs=p[to].wgt; 47 } 48 maxs=std::max(maxs,size-p[x].wgt); 49 if(maxs<maxsize) 50 { 51 maxsize=maxs; 52 root=x; 53 } 54 return ; 55 } 56 void update(int x,int f,int dep) 57 { 58 if(p[x].dis<=K) 59 has[p[x].dis]=std::min(has[p[x].dis],dep); 60 for(int i=p[x].hd;i;i=e[i].lst) 61 { 62 int to=e[i].twd; 63 if(to==f||p[to].vis) 64 continue; 65 update(to,x,dep+1); 66 } 67 return ; 68 } 69 void clear(int x,int f) 70 { 71 if(p[x].dis<=K) 72 has[p[x].dis]=0x3f3f3f3f; 73 for(int i=p[x].hd;i;i=e[i].lst) 74 { 75 int to=e[i].twd; 76 if(to==f||p[to].vis) 77 continue; 78 clear(to,x); 79 } 80 return ; 81 } 82 void ans_dfs(int x,int f,int dep) 83 { 84 if(p[x].dis<=K) 85 ans=std::min(ans,dep+has[K-p[x].dis]); 86 for(int i=p[x].hd;i;i=e[i].lst) 87 { 88 int to=e[i].twd; 89 if(to==f||p[to].vis) 90 continue; 91 p[to].dis=p[x].dis+e[i].vls; 92 ans_dfs(to,x,dep+1); 93 } 94 return ; 95 } 96 void bin_dfs(int x) 97 { 98 p[x].vis=true; 99 has[0]=0; 100 for(int i=p[x].hd;i;i=e[i].lst) 101 { 102 int to=e[i].twd; 103 if(p[to].vis) 104 continue; 105 p[to].dis=e[i].vls; 106 ans_dfs(to,to,1); 107 update(to,to,1); 108 } 109 for(int i=p[x].hd;i;i=e[i].lst) 110 { 111 int to=e[i].twd; 112 if(p[to].vis) 113 continue; 114 clear(to,to); 115 } 116 for(int i=p[x].hd;i;i=e[i].lst) 117 { 118 int to=e[i].twd; 119 if(p[to].vis) 120 continue; 121 root=0; 122 size=p[to].wgt; 123 maxsize=0x3f3f3f3f; 124 grc_dfs(to,to); 125 bin_dfs(root); 126 } 127 return ; 128 } 129 int main() 130 { 131 scanf("%d%d",&n,&K); 132 memset(has,0x3f,sizeof(has)); 133 has[0]=0; 134 for(int i=1;i<n;i++) 135 { 136 int a,b,c; 137 scanf("%d%d%d",&a,&b,&c); 138 a++,b++; 139 ade(a,b,c); 140 ade(b,a,c); 141 } 142 ans=0x3f3f3f3f; 143 root=0; 144 size=n; 145 maxsize=0x3f3f3f3f; 146 grc_dfs(1,1); 147 bin_dfs(root); 148 if(ans>=0x3f3f3f3f) 149 ans=-1; 150 printf("%d\n",ans); 151 return 0; 152 }