luogu P4149 [IOI2011] Race

传送门

点分治板子

纪念一下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\n",ans >= inf ? -1 : ans);
109     return 0;
110 }

 

posted @ 2018-12-10 10:06  白怀潇  阅读(136)  评论(0编辑  收藏  举报