[关闭]
@wsndy-xx 2018-05-09T17:59:02.000000Z 字数 2830 阅读 918

Luogu 4178 Tree

题解


题意同 Poj 1741
接下来给出两份代码

Code 1

  1. #include <bits/stdc++.h>
  2. const int N = 4e4 + 10;
  3. const int oo = 1e9;
  4. struct Node {int v, w, nxt;} G[N << 1];
  5. int n, k, now = 1, head[N];
  6. int size[N], maxson[N], dis[N];
  7. bool vis[N];
  8. int Max, Root, tot, Size;
  9. int Answer;
  10. #define gc getchar()
  11. inline int read() {
  12. int x = 0; char c = gc;
  13. while(c < '0' || c > '9') c = gc;
  14. while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
  15. return x;
  16. }
  17. inline void Add(int u, int v, int w) {G[now].v = v; G[now].w = w; G[now].nxt = head[u]; head[u] = now ++;}
  18. void Getroot(int u, int fa) {
  19. size[u] = 1;
  20. maxson[u] = 0;
  21. for(int i = head[u]; ~ i; i = G[i].nxt) {
  22. int v = G[i].v;
  23. if(!vis[v] && v != fa) {
  24. Getroot(v, u);
  25. size[u] += size[v];
  26. maxson[u] = std:: max(maxson[u], size[v]);
  27. }
  28. }
  29. maxson[u] = std:: max(maxson[u], Size - size[u]);
  30. if(maxson[u] < Max) {Max = maxson[u]; Root = u;}
  31. }
  32. void Getdis(int u, int fa, int len) {
  33. dis[++ tot] = len;
  34. for(int i = head[u]; ~ i; i = G[i].nxt) {
  35. int v = G[i].v;
  36. if(!vis[v] && v != fa) Getdis(v, u, len + G[i].w);
  37. }
  38. }
  39. int Calc(int u, int len) {
  40. tot = 0;
  41. for(int i = 1; i <= n; i ++) dis[i] = 0;
  42. Getdis(u, 0, len);
  43. std:: sort(dis + 1, dis + tot + 1);
  44. int L = 1, R = tot, ret(0);
  45. while(L <= R) {
  46. if(dis[L] + dis[R] <= k) ret += (R - L), L ++;
  47. else R --;
  48. }
  49. return ret;
  50. }
  51. void Getans(int u) {
  52. Answer += Calc(u, 0);
  53. vis[u] = 1;
  54. for(int i = head[u]; ~ i; i = G[i].nxt) {
  55. int v = G[i].v;
  56. if(!vis[v]) {
  57. Answer -= Calc(v, G[i].w);
  58. Size = size[v];
  59. Max = oo;
  60. Getroot(v, 0);
  61. Getans(Root);
  62. }
  63. }
  64. return ;
  65. }
  66. int main() {
  67. n = read();
  68. now = 1;
  69. for(int i = 1; i <= n; ++ i) head[i] = -1, vis[i] = 0;
  70. for(int i = 1; i < n; ++ i) {
  71. int u = read(), v = read(), w = read();
  72. Add(u, v, w), Add(v, u, w);
  73. }
  74. k = read();
  75. Answer = 0;
  76. Max = oo;
  77. Size = n;
  78. Getroot(1, 0);
  79. Getans(Root);
  80. std:: cout << Answer << "\n";
  81. return 0;
  82. }

Code 2

  1. #include <bits/stdc++.h>
  2. const int N = 4e4 + 10;
  3. const int oo = 1e9;
  4. struct Node {int v, w, nxt;} G[N << 1];
  5. int n, k, now = 1, head[N];
  6. int size[N], maxson[N], dis[N];
  7. bool vis[N];
  8. int Max, Root, tot, Size;
  9. int Answer;
  10. #define gc getchar()
  11. inline int read() {
  12. int x = 0; char c = gc;
  13. while(c < '0' || c > '9') c = gc;
  14. while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
  15. return x;
  16. }
  17. inline void Add(int u, int v, int w) {G[now].v = v; G[now].w = w; G[now].nxt = head[u]; head[u] = now ++;}
  18. void Getroot(int u, int fa) {
  19. size[u] = 1;
  20. maxson[u] = 0;
  21. for(int i = head[u]; ~ i; i = G[i].nxt) {
  22. int v = G[i].v;
  23. if(vis[v] || v == fa) continue ;
  24. Getroot(v, u);
  25. size[u] += size[v];
  26. maxson[u] = std:: max(maxson[u], size[v]);
  27. }
  28. maxson[u] = std:: max(maxson[u], n - size[u]);
  29. if(maxson[u] < maxson[Root]) Root = u;
  30. }
  31. void Getdis(int u, int fa, int len) {
  32. dis[++ tot] = len;
  33. for(int i = head[u]; ~ i; i = G[i].nxt) {
  34. int v = G[i].v;
  35. if(vis[v] || v == fa) continue ;
  36. Getdis(v, u, len + G[i].w);
  37. }
  38. }
  39. int Calc(int u, int len) {
  40. tot = 0;
  41. Getdis(u, 0, len);
  42. std:: sort(dis + 1, dis + tot + 1);
  43. int L = 1, R = tot, ret(0);
  44. while(L <= R) {
  45. while(dis[L] + dis[R] > k && R > L) R --;
  46. ret += R - L;
  47. L ++;
  48. }
  49. return ret;
  50. }
  51. void Getans(int u) {
  52. Answer += Calc(u, 0);
  53. vis[u] = 1;
  54. for(int i = head[u]; ~ i; i = G[i].nxt) {
  55. int v = G[i].v;
  56. if(!vis[v]) {
  57. Answer -= Calc(v, G[i].w);
  58. Root = 0;
  59. Getroot(v, 0);
  60. Getans(Root);
  61. }
  62. }
  63. return ;
  64. }
  65. int main() {
  66. n = read();
  67. now = 1;
  68. for(int i = 1; i <= n; ++ i) head[i] = -1, vis[i] = 0;
  69. for(int i = 1; i < n; ++ i) {
  70. int u = read(), v = read(), w = read();
  71. Add(u, v, w), Add(v, u, w);
  72. }
  73. k = read();
  74. Root = 0;
  75. maxson[Root] = n;
  76. Getroot(1, 0);
  77. Getans(Root);
  78. printf("%d\n", Answer);
  79. return 0;
  80. }

在Luogu Code1 会TLE 6 个测试点, Code2 可以 AC

代码不同之处

Code 1 在递归子树时,将树的大小看成整棵树的大小
其他没有什么太大区别
why???

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注