点分治板子
纪念一下1A
就是之前的一个然后距离和深度换一下
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define ms(a,b) memset(a,b,sizeof a) 5 #define rep(i,a,n) for(int i = a;i <= n;i++) 6 #define per(i,n,a) for(int i = n;i >= a;i--) 7 #define inf 1e8 8 using namespace std; 9 typedef long long ll; 10 #define B puts("GG") 11 ll read() { 12 ll as = 0,fu = 1; 13 char c = getchar(); 14 while(c < '0' || c > '9') { 15 if(c == '-') fu = -1; 16 c = getchar(); 17 } 18 while(c >= '0' && c <= '9') { 19 as = as * 10 + c - '0'; 20 c = getchar(); 21 } 22 return as * fu; 23 } 24 const int N = 200005; 25 //head 26 int n,k; 27 int head[N],nxt[N<<1],mo[N<<1],cnt; 28 int cst[N<<1]; 29 void _add(int x,int y,int w) { 30 nxt[++cnt] = head[x];head[x] = cnt; 31 mo[cnt] = y,cst[cnt] = w; 32 } 33 void add(int x,int y) { 34 int w = read(); 35 _add(x,y,w),_add(y,x,w); 36 } 37 38 bool vis[N]; 39 int sze[N],mx[N],sum,rt; 40 void getroot(int x,int f) { 41 sze[x] = 1,mx[x] = 0; 42 for(int i = head[x];i;i = nxt[i]) { 43 int sn = mo[i]; 44 if(sn == f || vis[sn]) continue; 45 getroot(sn,x); 46 sze[x] += sze[sn]; 47 mx[x] = max(mx[x],sze[sn]); 48 } 49 mx[x] = max(mx[x],sum - sze[x]); 50 if(mx[x] < mx[rt]) rt = x; 51 } 52 53 int tmp[1000005]; 54 int ans = inf; 55 void getdis(int x,int f,int dis,int cnt) { 56 if(dis > k) return; 57 ans = min(ans,tmp[k - dis] + cnt); 58 // minn[dis[x]] = min(minn[dis[x]],dep[x]); 59 for(int i = head[x];i;i = nxt[i]) { 60 int sn = mo[i]; 61 if(sn == f || vis[sn]) continue; 62 getdis(sn,x,dis + cst[i],cnt + 1); 63 } 64 } 65 66 void update(int x,int f,int dis,int cnt) { 67 if(dis > k) return; 68 tmp[dis] = min(tmp[dis],cnt); 69 for(int i = head[x];i;i = nxt[i]) { 70 int sn = mo[i]; 71 if(sn == f || vis[sn]) continue; 72 update(sn,x,dis + cst[i],cnt + 1); 73 } 74 } 75 76 void clear(int x,int f,int dis) { 77 if(dis >= k) return; 78 tmp[dis] = inf; 79 for(int i = head[x];i;i = nxt[i]) { 80 int sn = mo[i]; 81 if(sn == f || vis[sn]) continue; 82 clear(sn,x,dis + cst[i]); 83 } 84 } 85 86 void solve(int x) { 87 tmp[0] = 0,vis[x] = 1; 88 for(int i = head[x];i;i = nxt[i]) { 89 int sn = mo[i]; 90 if(vis[sn]) continue; 91 getdis(sn,x,cst[i],1),update(sn,x,cst[i],1); 92 } 93 clear(x,0,0); 94 for(int i = head[x];i;i = nxt[i]) { 95 int sn = mo[i]; 96 if(vis[sn]) continue; 97 sum = sze[sn],mx[rt = 0] = inf; 98 getroot(sn,sn),solve(rt); 99 } 100 } 101 102 int main() { 103 n = read(),k = read(); 104 rep(i,2,n) add(read()+1,read()+1); 105 rep(i,1,k) tmp[i] = inf; 106 sum = n,mx[rt = 0] = inf; 107 getroot(1,1),solve(rt); 108 printf("%d ",ans >= inf ? -1 : ans); 109 return 0; 110 }