POJ 1741(树分治)

﹏ヽ暗。殇╰゛Y 2022-08-05 00:57 244阅读 0赞

树分治第一题

论文题:

树的点分治

  1. // whn6325689
  2. // Mr.Phoebe
  3. // http://blog.csdn.net/u013007900
  4. #include <algorithm>
  5. #include <iostream>
  6. #include <iomanip>
  7. #include <cstring>
  8. #include <climits>
  9. #include <complex>
  10. #include <fstream>
  11. #include <cassert>
  12. #include <cstdio>
  13. #include <bitset>
  14. #include <vector>
  15. #include <deque>
  16. #include <queue>
  17. #include <stack>
  18. #include <ctime>
  19. #include <set>
  20. #include <map>
  21. #include <cmath>
  22. #include <functional>
  23. #include <numeric>
  24. #pragma comment(linker, "/STACK:1024000000,1024000000")
  25. using namespace std;
  26. typedef long long ll;
  27. typedef long double ld;
  28. typedef pair<ll, ll> pll;
  29. typedef complex<ld> point;
  30. typedef pair<int, int> pii;
  31. typedef pair<pii, int> piii;
  32. typedef vector<int> vi;
  33. #define CLR(x,y) memset(x,y,sizeof(x))
  34. #define mp(x,y) make_pair(x,y)
  35. #define pb(x) push_back(x)
  36. #define lowbit(x) (x&(-x))
  37. #define MID(x,y) (x+((y-x)>>1))
  38. #define speed std::ios::sync_with_stdio(false);
  39. #define eps 1e-9
  40. #define PI acos(-1.0)
  41. #define INF 0x3f3f3f3f
  42. #define LLINF 1LL<<62
  43. template<class T>
  44. inline bool read(T &n)
  45. {
  46. T x = 0, tmp = 1;
  47. char c = getchar();
  48. while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
  49. if(c == EOF) return false;
  50. if(c == '-') c = getchar(), tmp = -1;
  51. while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
  52. n = x*tmp;
  53. return true;
  54. }
  55. template <class T>
  56. inline void write(T n)
  57. {
  58. if(n < 0)
  59. {
  60. putchar('-');
  61. n = -n;
  62. }
  63. int len = 0,data[20];
  64. while(n)
  65. {
  66. data[len++] = n%10;
  67. n /= 10;
  68. }
  69. if(!len) data[len++] = 0;
  70. while(len--) putchar(data[len]+48);
  71. }
  72. //-----------------------------------
  73. const int MAXN=10010;
  74. struct Edge
  75. {
  76. int v,nex,w;
  77. } e[MAXN<<1];
  78. int h[MAXN],tot;
  79. int vis[MAXN],n,k;
  80. int sz[MAXN],num[MAXN],dep[MAXN];
  81. int root,N;
  82. int st[MAXN],top,ans;
  83. void init()
  84. {
  85. CLR(h,-1);CLR(vis,0);
  86. root=0;num[0]=N=n;ans=0;tot=0;
  87. }
  88. void addedge(int u,int v,int w)
  89. {
  90. e[tot].v=v;
  91. e[tot].w=w;
  92. e[tot].nex=h[u];
  93. h[u]=tot++;
  94. }
  95. int dfs_root(int u,int fa=-1)
  96. {
  97. sz[u]=1;num[u]=0;
  98. for(int i=h[u];~i;i=e[i].nex)
  99. {
  100. int v=e[i].v;
  101. if(fa==v || vis[v]) continue;
  102. sz[u]+=dfs_root(v,u);
  103. num[u]=max(num[u],sz[v]);
  104. }
  105. num[u]=max(num[u],N-sz[u]);
  106. if(num[u]<num[root])
  107. root=u;
  108. return sz[u];
  109. }
  110. int dfs_dep(int u,int fa=-1)
  111. {
  112. if(dep[u]<=k) st[top++]=dep[u];
  113. sz[u]=1;
  114. for(int i=h[u];~i;i=e[i].nex)
  115. {
  116. int v=e[i].v;
  117. if(fa==v || vis[v]) continue;
  118. dep[v]=dep[u]+e[i].w;
  119. sz[u]+=dfs_dep(v,u);;
  120. }
  121. return sz[u];
  122. }
  123. int get_num(int u,int len)
  124. {
  125. top=0;
  126. dep[u]=len;
  127. dfs_dep(u);
  128. sort(st,st+top);
  129. int ans=0,r=top-1;
  130. for(int l=0;l<r;l++)
  131. {
  132. while(r>l && st[l]+st[r]>k)
  133. r--;
  134. ans+=r-l;
  135. }
  136. return ans;
  137. }
  138. void dfs(int u)
  139. {
  140. vis[u]=1;
  141. ans+=get_num(u,0);
  142. for(int i=h[u];~i;i=e[i].nex)
  143. {
  144. int v=e[i].v;
  145. if(vis[v]) continue;
  146. ans-=get_num(v,e[i].w);
  147. root=0;N=sz[v];
  148. dfs_root(v);
  149. dfs(root);
  150. }
  151. }
  152. int main()
  153. {
  154. while(read(n)&&read(k)&&(n+k))
  155. {
  156. init();
  157. for(int i=1,u,v,w;i<n;i++)
  158. {
  159. read(u),read(v),read(w);
  160. addedge(u,v,w);addedge(v,u,w);
  161. }
  162. dfs_root(1);
  163. dfs(root);
  164. write(ans),putchar('\n');
  165. }
  166. return 0;
  167. }

发表评论

表情:
评论列表 (有 0 条评论,244人围观)

还没有评论,来说两句吧...

相关阅读

    相关 BZOJ1095 动态点分治(点分)

    题意: 操作1.修改一个点的颜色(黑白互换) 操作2.询问所有黑色点之间最远距离   点分树:当我们可以形如点分治一样的统计答案,即每次确定一个重心,然后计算他们子树之

    相关 Trie POJ 1056

    Trie树提供给了一种能够在字符串的长度n时间内判断出来是否在已有集合中已经存在这个字符串了。 1056是判断前缀码的问题。如果所有字符串都不是其他的字符串的前缀的话,那么就

    相关 POJ 2114 Boatherds 点分治

    问是否存在长度等于K的路径。就是将统计小于等于K的换成统计等于K的条数,只要最后统计出来的等于K的数量大于0就是存在。其他一点没变,还是那个论文题的点分治。 // w

    相关 [poj1741]Tree

    点分治模板题,可以将同一棵树的链分为两种:1.通过重心;2.在子树内部。第2种可以搜下去,第1种的答案即$\\sum\_\{i,j\}\[di+dj<=m\]-\\sum\\l

    相关 浅谈分治

    点分治 概述 通过求树的重心来给无根树找到一个根。 使得分出的子树的结点个数均不大于n/2,使每次点分治删点后联通块大小减少至少一半。 保证递归层数最多logn。 ...