[关闭]
@ZCDHJ 2019-10-25T12:34:06.000000Z 字数 1966 阅读 635

Codeforces911F Tree Destruction

未分类


首先距离一个点最远的点一定是直径上的某个端点。由此可以获得一个贪心策略:优先删除不在直径上的点,然后删除在直径上的点就行了。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <vector>
  4. typedef long long LL;
  5. const int MAXN = 2e5;
  6. int n, edge, ans1, lu, lv;
  7. int f[MAXN | 1], fst[MAXN | 1], depth[MAXN | 1], father[MAXN | 1];
  8. int calc[MAXN][2];
  9. bool vis[MAXN | 1], flag[MAXN | 1];
  10. LL ans;
  11. int dp[MAXN | 1];
  12. std::vector < int > vec[2];
  13. struct Edge {
  14. int to, nxt;
  15. Edge() : to(0), nxt(0) {}
  16. Edge(int a, int b) : to(b), nxt(fst[a]) {}
  17. } e[MAXN << 1];
  18. inline int read() {
  19. register int x = 0;
  20. register char ch = getchar();
  21. while (!isdigit(ch)) ch = getchar();
  22. while (isdigit(ch)) {
  23. x = x * 10 + ch - '0';
  24. ch = getchar();
  25. }
  26. return x;
  27. }
  28. inline void add_edge(int x, int y) {
  29. e[++edge] = Edge(x, y);
  30. fst[x] = edge;
  31. }
  32. void dfs1(int x, int fa) {
  33. father[x] = fa;
  34. depth[x] = depth[fa] + 1;
  35. dp[x] = 1;
  36. f[x] = x;
  37. for (int k = fst[x]; k; k = e[k].nxt) {
  38. int to = e[k].to;
  39. if (to == fa) continue;
  40. dfs1(to, x);
  41. if (dp[to] + dp[x] > ans) {
  42. ans = dp[x] + dp[to];
  43. lu = f[x];
  44. lv = f[to];
  45. }
  46. if (dp[to] + 1 > dp[x]) {
  47. dp[x] = dp[to] + 1;
  48. f[x] = f[to];
  49. }
  50. }
  51. }
  52. void dfs2(int x, int dis, int fa, int from) {
  53. if (!vis[x]) {
  54. if (dis > calc[x][0]) {
  55. calc[x][0] = dis;
  56. calc[x][1] = from;
  57. }
  58. if (from == lv) ans += calc[x][0];
  59. }
  60. for (int k = fst[x]; k; k = e[k].nxt) {
  61. int to = e[k].to;
  62. if (to == fa) continue;
  63. dfs2(to, dis + 1, x, from);
  64. }
  65. }
  66. void dfs3(int x) {
  67. flag[x] = 1;
  68. for (int k = fst[x]; k; k = e[k].nxt) {
  69. int to = e[k].to;
  70. if (vis[to] || flag[to]) continue;
  71. dfs3(to);
  72. }
  73. if (!vis[x]) {
  74. printf("%d %d %d\n", x, calc[x][1], x);
  75. }
  76. }
  77. int main() {
  78. n = read();
  79. for (int i = 1; i < n; ++i) {
  80. int u = read(), v = read();
  81. add_edge(u, v);
  82. add_edge(v, u);
  83. }
  84. dfs1(1, 0);
  85. ans = ans * (ans - 1) / 2;
  86. int tx = lu, ty = lv;
  87. if (depth[tx] < depth[ty]) std::swap(tx, ty);
  88. while (depth[tx] > depth[ty]) vis[tx] = 1, vec[0].push_back(tx), tx = father[tx];
  89. while (tx != ty) vis[tx] = 1, vis[ty] = 1, vec[0].push_back(tx), vec[1].push_back(ty), tx = father[tx], ty = father[ty];
  90. vis[tx] = 1;
  91. vec[0].push_back(tx);
  92. for (int i = vec[1].size() - 1; i >= 0; --i) vec[0].push_back(vec[1][i]);
  93. vec[1].clear();
  94. dfs2(lu, 0, 0, lu);
  95. dfs2(lv, 0, 0, lv);
  96. printf("%lld\n", ans);
  97. for (std::vector < int > :: iterator it = vec[0].begin(); it != vec[0].end(); ++it) {
  98. int now = *it;
  99. dfs3(now);
  100. }
  101. for (int i = 0; i < vec[0].size() - 1; ++i) {
  102. printf("%d %d %d\n", vec[0][i], vec[0][vec[0].size() - 1], vec[0][i]);
  103. }
  104. return 0;
  105. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注