洛谷 P5021 [NOIP2018]赛道重建

传送门

思路

思路就是常规的思路,所以就不说了……我就是来记录一下我的\(AC\)之路的,真的是太爽了

没错……我也是一个个打的部分分,最后终于AC的,至于为什么中间又会有\(35\)、\(25\)、\(0\)这样的分数……纯粹是因为我犯了zz错误……

代码

1、\(b_i = a_i + 1\) 链的情况

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. inline int read() {
  4. char c = getchar();
  5. int x = 0, f = 1;
  6. for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
  7. for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
  8. return x * f;
  9. }
  10. const int N = 50011;
  11. int a[N], n, m, cnt, head[N], sum;
  12. struct node {
  13. int to, nxt, val;
  14. } e[N << 1];
  15. inline void add(int from, int to, int w) {
  16. e[++cnt].to = to;
  17. e[cnt].val = w;
  18. e[cnt].nxt = head[from];
  19. head[from] = cnt;
  20. }
  21. void dfs(int x, int fa) {
  22. for(int i = head[x]; i ; i = e[i].nxt) {
  23. int y = e[i].to;
  24. if(y == fa) continue;
  25. dfs(y, x);
  26. a[x] = e[i].val;
  27. }
  28. }
  29. int check(int k) {
  30. int t = 0, now = 1;
  31. for(int i = 1; i < n; i++) {
  32. if(now + a[i] >= k) {
  33. now = 0;
  34. t++;
  35. }
  36. else now += a[i];
  37. }
  38. return t >= m;
  39. }
  40. int main() {
  41. n = read(), m = read();
  42. for(int i = 1; i < n; i++) {
  43. int u = read(), v = read(), w = read();
  44. add(u, v, w);
  45. add(v, u, w);
  46. sum += w;
  47. }
  48. dfs(1, 0);
  49. int l = 1, r = sum, mid;
  50. while(l < r) {
  51. mid = (l + r) >> 1;
  52. if(check(mid)) l = mid;
  53. else r = mid - 1;
  54. }
  55. cout << l << '\n';
  56. }

2、\(m = 1\) 求树的直径

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. inline int read() {
  4. char c = getchar();
  5. int x = 0, f = 1;
  6. for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
  7. for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
  8. return x * f;
  9. }
  10. const int N = 50011;
  11. int a[N], n, m, cnt, head[N], sum, ans;
  12. struct node {
  13. int to, nxt, val;
  14. } e[N << 1];
  15. inline void add(int from, int to, int w) {
  16. e[++cnt].to = to;
  17. e[cnt].val = w;
  18. e[cnt].nxt = head[from];
  19. head[from] = cnt;
  20. }
  21. int dfs(int x,int fa) {
  22. int sum1 = 0, sum2 = 0;
  23. for(int i = head[x]; i; i = e[i].nxt) {
  24. int y = e[i].to;
  25. if(y == fa) continue;
  26. sum2 = max(sum2, dfs(y, x) + e[i].val);
  27. if(sum2 > sum1) swap(sum1, sum2);
  28. }
  29. ans = max(ans, sum1 + sum2);
  30. return sum1;
  31. }
  32. int main() {
  33. n = read(), m = read();
  34. for(int i = 1; i < n; i++) {
  35. int u = read(), v = read(), w = read();
  36. add(u, v, w);
  37. add(v, u, w);
  38. sum += w;
  39. }
  40. dfs(1, 0);
  41. cout << ans << '\n';
  42. }

3、\(a_i = 1\) 菊花图

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. inline int read() {
  4. char c = getchar();
  5. int x = 0, f = 1;
  6. for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
  7. for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
  8. return x * f;
  9. }
  10. const int N = 50011;
  11. const int inf = 0x3f3f3f3f;
  12. int a[N], n, m, cnt, head[N], sum, ans;
  13. struct node {
  14. int to, nxt, val;
  15. } e[N << 1];
  16. inline void add(int from, int to, int w) {
  17. e[++cnt].to = to;
  18. e[cnt].val = w;
  19. e[cnt].nxt = head[from];
  20. head[from] = cnt;
  21. }
  22. bool cmp(int a, int b) {
  23. return a > b;
  24. }
  25. int main() {
  26. n = read(), m = read();
  27. for(int i = 1; i < n; i++) {
  28. int u = read(), v = read(), w = read();
  29. add(u, v, w);
  30. add(v, u, w);
  31. sum += w;
  32. }
  33. for(int i = head[1], y; i; i = e[i].nxt) {
  34. y = e[i].to;
  35. a[y - 1] = e[i].val;
  36. }
  37. sort(a + 1, a + n, cmp);
  38. int ans = inf;
  39. for(int i = 1; i <= m; i++)
  40. ans = min(ans, a[i] + a[2 * m - i + 1]);
  41. cout << ans << '\n';
  42. return 0;
  43. }

4、混起来的部分分

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. inline int read() {
  4. char c = getchar();
  5. int x = 0, f = 1;
  6. for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
  7. for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
  8. return x * f;
  9. }
  10. const int N = 50011;
  11. const int inf = 0x3f3f3f3f;
  12. int a[N], n, m, cnt, head[N], sum, ans;
  13. struct node {
  14. int to, nxt, val;
  15. } e[N << 1];
  16. inline void add(int from, int to, int w) {
  17. e[++cnt].to = to;
  18. e[cnt].val = w;
  19. e[cnt].nxt = head[from];
  20. head[from] = cnt;
  21. }
  22. namespace subtask1 {
  23. int a[N];
  24. void dfs(int x, int fa) {
  25. for(int i = head[x]; i ; i = e[i].nxt) {
  26. int y = e[i].to;
  27. if(y == fa) continue;
  28. dfs(y, x);
  29. a[x] = e[i].val;
  30. }
  31. }
  32. int check(int k) {
  33. int t = 0, now = 1;
  34. for(int i = 1; i < n; i++) {
  35. if(now + a[i] >= k) {
  36. now = 0;
  37. t++;
  38. } else now += a[i];
  39. }
  40. return t >= m;
  41. }
  42. void solve() {
  43. dfs(1, 0);
  44. int l = 1, r = sum, mid;
  45. while(l < r) {
  46. mid = (l + r + 1) >> 1;
  47. if(check(mid)) l = mid;
  48. else r = mid - 1;
  49. }
  50. cout << l << '\n';
  51. }
  52. }
  53. namespace subtask2 {
  54. int dfs(int x,int fa) {
  55. int sum1 = 0, sum2 = 0;
  56. for(int i = head[x]; i; i = e[i].nxt) {
  57. int y = e[i].to;
  58. if(y == fa) continue;
  59. sum2 = max(sum2, dfs(y, x) + e[i].val);
  60. if(sum2 > sum1) swap(sum1, sum2);
  61. }
  62. ans = max(ans, sum1 + sum2);
  63. return sum1;
  64. }
  65. void solve() {
  66. dfs(1, 0);
  67. cout << ans << '\n';
  68. }
  69. }
  70. namespace subtask3 {
  71. bool cmp(int a, int b) {
  72. return a > b;
  73. }
  74. void solve() {
  75. for(int i = head[1], y; i; i = e[i].nxt) {
  76. y = e[i].to;
  77. a[y - 1] = e[i].val;
  78. }
  79. sort(a + 1, a + n, cmp);
  80. int ans = inf;
  81. for(int i = 1; i <= m; i++)
  82. ans = min(ans, a[i] + a[2 * m - i + 1]);
  83. cout << ans << '\n';
  84. }
  85. }
  86. int main() {
  87. n = read(), m = read();
  88. int flag = 1, f = 1;
  89. for(int i = 1; i < n; i++) {
  90. int u = read(), v = read(), w = read();
  91. add(u, v, w);
  92. add(v, u, w);
  93. if(u != 1) flag = 0;
  94. if(v != u + 1) f = 0;
  95. sum += w;
  96. }
  97. if(flag) {
  98. subtask3::solve();
  99. }
  100. else if(f){
  101. subtask1::solve();
  102. }
  103. else {
  104. subtask2::solve();
  105. }
  106. return 0;
  107. }

5、正解!!(\(multiset\))

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. inline int read() {
  4. char c = getchar();
  5. int x = 0, f = 1;
  6. for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
  7. for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
  8. return x * f;
  9. }
  10. const int N = 50011;
  11. const int inf = 0x3f3f3f3f;
  12. int a[N], n, m, cnt, head[N], ans, up;
  13. struct node {
  14. int to, nxt, val;
  15. } e[N << 1];
  16. multiset<int> s[N];
  17. multiset<int>::iterator it;
  18. inline void add(int from, int to, int w) {
  19. e[++cnt].to = to;
  20. e[cnt].val = w;
  21. e[cnt].nxt = head[from];
  22. head[from] = cnt;
  23. }
  24. int dfs(int x, int fa, int k) {
  25. s[x].clear();
  26. int w;
  27. for(int i = head[x]; i; i = e[i].nxt) {
  28. int y = e[i].to;
  29. if(y == fa) continue;
  30. w = dfs(y, x, k) + e[i].val;
  31. if(w >= k) ans++;
  32. else s[x].insert(w);
  33. }
  34. int maxn = 0;
  35. while(!s[x].empty()) {
  36. if(s[x].size() == 1) {
  37. return max(maxn, *s[x].begin());
  38. }
  39. it = s[x].lower_bound(k - *s[x].begin());
  40. if(it == s[x].begin() && s[x].count(*it) == 1) it++;
  41. if(it == s[x].end()) {
  42. maxn = max(maxn, *s[x].begin());
  43. s[x].erase(s[x].find(*s[x].begin()));
  44. } else {
  45. ans++;
  46. s[x].erase(s[x].find(*it));
  47. s[x].erase(s[x].find(*s[x].begin()));
  48. }
  49. }
  50. return maxn;
  51. }
  52. int dfs1(int x,int fa) {
  53. int sum1 = 0, sum2 = 0;
  54. for(int i = head[x], y; i; i = e[i].nxt) {
  55. y=e[i].to;
  56. if(y == fa) continue;
  57. sum2 = max(sum2, dfs1(y, x) + e[i].val);
  58. if(sum1 < sum2) swap(sum1, sum2);
  59. }
  60. up = max(up, sum1 + sum2);
  61. return sum1;
  62. }
  63. int check(int k) {
  64. ans = 0;
  65. dfs(1, 0, k);
  66. if(ans >= m) return 1;
  67. return 0;
  68. }
  69. int main() {
  70. n = read(), m = read();
  71. for(int i = 1; i < n; i++) {
  72. int u = read(), v = read(), w = read();
  73. add(u, v, w);
  74. add(v, u, w);
  75. }
  76. dfs1(1, 0);
  77. int l = 1, r = up, mid;
  78. while(l < r) {
  79. mid = (l + r + 1) >> 1;
  80. if(check(mid)) l = mid;
  81. else r = mid - 1;
  82. }
  83. cout << l << '\n';
  84. }

洛谷 P5021 [NOIP2018]赛道重建的更多相关文章

  1. 洛谷P5021 赛道修建 NOIp2018 贪心+二分答案

    正解:贪心+LCA+二分答案 解题报告: 想先港下部分分qwq因为我部分分只拿到了10ptsQAQ(时间不够不是理由,其实还是太弱,所以要想很久,所以才时间不够QAQ m=1 找直径长度,完 一条链 ...

  2. 洛谷P5021 赛道修建

    题目 首先考虑二分,然后发现最小长度越大的话,赛道就越少.所以可以用最终的赛道个数来判断长度是否合理.问题转化为给定一个长度,问最多有多少条互不重叠路径比这个给定长度大. 考虑贪心,毕竟贪心也是二分c ...

  3. 洛谷P1119 灾后重建[Floyd]

    题目背景 B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重建完成的村庄的公路才能 ...

  4. 洛谷——P1119 灾后重建

    P1119 灾后重建 题目背景 B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重 ...

  5. 洛谷 P4198 楼房重建 线段树维护单调栈

    P4198 楼房重建 题目链接 https://www.luogu.org/problemnew/show/P4198 题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上 ...

  6. 洛谷 P1119 灾后重建——dijstra

    先上一波题目 https://www.luogu.org/problem/P1119 这道题我们可以将询问按时间排序 然后随着询问将相应已经重建成功的点进行操作 每次更新一个点就以他为起点跑一遍dij ...

  7. 洛谷 P1119 灾后重建 最短路+Floyd算法

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 总结 题面 题目链接 P1119 灾后重建 题目描述 B地区在地震过后,所有村 ...

  8. 洛谷 [P1119] 灾后重建

    我们发现每次询问都是对于任意两点的,所以这是一道多源最短路径的题,多源最短路径,我们首先想到floyd,因为询问的时间是不降的,所以对于每次询问,我们将还没有进行松弛操作的的点k操作. #includ ...

  9. 洛谷P1119灾后重建

    题目 做一个替我们首先要明确一下数据范围,n<=200,说明n^3的算法是可以过得,而且这个题很明显是一个图论题, 所以我们很容易想到这个题可以用folyd, 但是我在做这个题的时候因为没有深刻 ...

随机推荐

  1. CompletableService

    public class CompletableServiceTest { public static void main(String[] args) throws ExecutionExcepti ...

  2. Python自定义注解

    Python3.0之后加入新特性Decorators,以@为标记修饰function和class.有点类似c++的宏和java的注解.Decorators用以修饰约束function和class,分为 ...

  3. 在 .NET Core 中使用异步的 ADO.NET 的简单示例

    直接贴代码: Program.cs using Microsoft.Extensions.Configuration; using System; using System.Data; using S ...

  4. AdminLTE 3.0发布了

    在11月2日,作者正式发布了AdminLTE 3.0版本.该版本基于Bootstrap 4.x.使用Bootstrap 4.x的小伙伴可以愉快的使用AdminLTE. Github AdminLTE是 ...

  5. ASP.NET Web API 2 的返回结果

    HttpResponseMessage IHttpActionResult void 某些其他类型 总结归纳 原文地址:https://www.cnblogs.com/xgzh/p/11208611. ...

  6. selenium简单使用

    简介 Selenium是一个用于Web应用程序测试的工具.Selenium可以直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Fi ...

  7. Java生鲜电商平台-物流配送的设计与架构

    Java生鲜电商平台-物流配送的设计与架构 说明:由于Java开源生鲜电商平台是属于自建物流系统,也就是买家下的单,需要公司派物流团队进行派送.            业务需求中买家的下单时间控制在: ...

  8. 五分钟看懂UML类图与类的关系详解

    在画类图的时候,理清类和类之间的关系是重点.类的关系有泛化(Generalization).实现(Realization).依赖(Dependency)和关联(Association).其中关联又分为 ...

  9. tkinter为多个窗口设置相同的icon报错

    import threading import tkinter from PIL import Image, ImageTk def show_window(): window = tkinter.T ...

  10. Docker Desktop for Windows 安装步骤

    Docker Desktop for Windows 安装要求 Docker Desktop for Windows需要运行Microsoft Hyper-V.如果需要,Docker Desktop ...