最简单的点分治
淀粉质的思想:
“分而治之”,缩小问题规模,合并求解;
1 #include<cstdio> 2 #include<cmath> 3 #include<cstring> 4 #include<algorithm> 5 #include<iostream> 6 using namespace std; 7 #define up(i,l,r) for(register int i = (l); i <= (r); ++i) 8 #define dn(i,l,r) for(register int i = (l); i >= (r); --i) 9 #define ll long long 10 #define re register 11 using namespace std; 12 13 template <typename T> void in(T &x) { 14 x = 0; T f = 1; char ch = getchar(); 15 while(!isdigit(ch)) {if(ch == ‘-‘) f = -1; ch = getchar();} 16 while( isdigit(ch)) {x = 10 * x + ch - 48; ch = getchar();} 17 x *= f; 18 } 19 20 template <typename T> void out(T x) { 21 if(x < 0) x = -x , putchar(‘-‘); 22 if(x > 9) out(x/10); 23 putchar(x%10 + 48); 24 } 25 //--------------------------------------------------------- 26 27 const int N = 40007; 28 29 struct edge { 30 int v,w,nxt; 31 } e[N<<1];int tot,head[N]; 32 33 void add(int u,int v,int w) { 34 e[++tot].v = v; 35 e[tot].w = w; 36 e[tot].nxt = head[u]; 37 head[u] = tot; 38 } 39 //--------------------------------------------------------- 40 41 int n,k,ans; 42 int size[N]; 43 int Tsize,cnt,rt; 44 int cdis[N],dis[N]; 45 bool vis[N]; 46 47 int f[N]; 48 void get_rt(int u,int fa) { 49 size[u] = 1; f[u] = 0; 50 for(re int i = head[u]; i; i = e[i].nxt) { 51 int v = e[i].v; if(v == fa || vis[v]) continue; 52 get_rt(v,u); 53 size[u] += size[v]; 54 f[u] = max(size[v],f[u]); 55 } 56 f[u] = max(f[u],Tsize-size[u]); 57 if(f[u] < f[rt]) rt = u; 58 } 59 60 void get_dis(int u,int fa) { 61 cdis[++cnt] = dis[u]; 62 for(re int i = head[u]; i; i = e[i].nxt) { 63 int v = e[i].v; if(v == fa || vis[v]) continue; 64 dis[v] = dis[u] + e[i].w; get_dis(v,u); 65 } 66 } 67 68 int calc(int u) { 69 cnt = 0,get_dis(u,0); 70 sort(cdis+1,cdis+cnt+1); 71 int l = 1,r = cnt,sum = 0; 72 while(l < r) { 73 if(cdis[l] + cdis[r] <= k) sum += r-l,++l; 74 else --r; 75 } 76 return sum; 77 } 78 79 void new_tree(int u) { 80 vis[u] = 1; dis[u] = 0;// 81 ans += calc(u); 82 for(re int i = head[u]; i; i = e[i].nxt) { 83 int v = e[i].v; if(vis[v]) continue; 84 dis[v] = e[i].w;// 85 ans -= calc(v); 86 rt = 0,Tsize = size[v]; 87 get_rt(v,0); new_tree(rt); 88 } 89 } 90 91 92 void init() { 93 memset(head,0,sizeof(head)); 94 memset(vis,0,sizeof(vis)); 95 Tsize = n,rt = 0,f[0] = n+1; ans = 0; 96 } 97 98 int main() { 99 freopen("input.txt","r",stdin); 100 in(n); 101 init(); int x,y,w; 102 up(i,1,n-1) in(x),in(y),in(w),add(x,y,w),add(y,x,w);in(k); 103 get_rt(1,0); new_tree(rt); 104 out(ans); putchar(‘\n‘); 105 }
原文地址:https://www.cnblogs.com/mzg1805/p/10737145.html
时间: 2024-10-08 18:36:47