洛谷 P5021 [NOIP2018]赛道重建

传送门

思路

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

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

代码

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

#include <bits/stdc++.h>
using namespace std; inline int read() {
char c = getchar();
int x = 0, f = 1;
for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
return x * f;
} const int N = 50011;
int a[N], n, m, cnt, head[N], sum; struct node {
int to, nxt, val;
} e[N << 1]; inline void add(int from, int to, int w) {
e[++cnt].to = to;
e[cnt].val = w;
e[cnt].nxt = head[from];
head[from] = cnt;
} void dfs(int x, int fa) {
for(int i = head[x]; i ; i = e[i].nxt) {
int y = e[i].to;
if(y == fa) continue;
dfs(y, x);
a[x] = e[i].val;
}
} int check(int k) {
int t = 0, now = 1;
for(int i = 1; i < n; i++) {
if(now + a[i] >= k) {
now = 0;
t++;
}
else now += a[i];
}
return t >= m;
} int main() {
n = read(), m = read();
for(int i = 1; i < n; i++) {
int u = read(), v = read(), w = read();
add(u, v, w);
add(v, u, w);
sum += w;
}
dfs(1, 0);
int l = 1, r = sum, mid;
while(l < r) {
mid = (l + r) >> 1;
if(check(mid)) l = mid;
else r = mid - 1;
}
cout << l << '\n';
}

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

#include <bits/stdc++.h>
using namespace std; inline int read() {
char c = getchar();
int x = 0, f = 1;
for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
return x * f;
} const int N = 50011;
int a[N], n, m, cnt, head[N], sum, ans; struct node {
int to, nxt, val;
} e[N << 1]; inline void add(int from, int to, int w) {
e[++cnt].to = to;
e[cnt].val = w;
e[cnt].nxt = head[from];
head[from] = cnt;
} int dfs(int x,int fa) {
int sum1 = 0, sum2 = 0;
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(y == fa) continue;
sum2 = max(sum2, dfs(y, x) + e[i].val);
if(sum2 > sum1) swap(sum1, sum2);
}
ans = max(ans, sum1 + sum2);
return sum1;
} int main() {
n = read(), m = read();
for(int i = 1; i < n; i++) {
int u = read(), v = read(), w = read();
add(u, v, w);
add(v, u, w);
sum += w;
}
dfs(1, 0);
cout << ans << '\n';
}

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

#include <bits/stdc++.h>
using namespace std; inline int read() {
char c = getchar();
int x = 0, f = 1;
for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
return x * f;
} const int N = 50011;
const int inf = 0x3f3f3f3f;
int a[N], n, m, cnt, head[N], sum, ans; struct node {
int to, nxt, val;
} e[N << 1]; inline void add(int from, int to, int w) {
e[++cnt].to = to;
e[cnt].val = w;
e[cnt].nxt = head[from];
head[from] = cnt;
} bool cmp(int a, int b) {
return a > b;
} int main() {
n = read(), m = read();
for(int i = 1; i < n; i++) {
int u = read(), v = read(), w = read();
add(u, v, w);
add(v, u, w);
sum += w;
}
for(int i = head[1], y; i; i = e[i].nxt) {
y = e[i].to;
a[y - 1] = e[i].val;
}
sort(a + 1, a + n, cmp);
int ans = inf;
for(int i = 1; i <= m; i++)
ans = min(ans, a[i] + a[2 * m - i + 1]);
cout << ans << '\n';
return 0;
}

4、混起来的部分分

#include <bits/stdc++.h>
using namespace std; inline int read() {
char c = getchar();
int x = 0, f = 1;
for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
return x * f;
} const int N = 50011;
const int inf = 0x3f3f3f3f;
int a[N], n, m, cnt, head[N], sum, ans; struct node {
int to, nxt, val;
} e[N << 1]; inline void add(int from, int to, int w) {
e[++cnt].to = to;
e[cnt].val = w;
e[cnt].nxt = head[from];
head[from] = cnt;
} namespace subtask1 {
int a[N];
void dfs(int x, int fa) {
for(int i = head[x]; i ; i = e[i].nxt) {
int y = e[i].to;
if(y == fa) continue;
dfs(y, x);
a[x] = e[i].val;
}
} int check(int k) {
int t = 0, now = 1;
for(int i = 1; i < n; i++) {
if(now + a[i] >= k) {
now = 0;
t++;
} else now += a[i];
}
return t >= m;
} void solve() {
dfs(1, 0);
int l = 1, r = sum, mid;
while(l < r) {
mid = (l + r + 1) >> 1;
if(check(mid)) l = mid;
else r = mid - 1;
}
cout << l << '\n';
}
} namespace subtask2 {
int dfs(int x,int fa) {
int sum1 = 0, sum2 = 0;
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(y == fa) continue;
sum2 = max(sum2, dfs(y, x) + e[i].val);
if(sum2 > sum1) swap(sum1, sum2);
}
ans = max(ans, sum1 + sum2);
return sum1;
}
void solve() {
dfs(1, 0);
cout << ans << '\n';
}
} namespace subtask3 {
bool cmp(int a, int b) {
return a > b;
}
void solve() {
for(int i = head[1], y; i; i = e[i].nxt) {
y = e[i].to;
a[y - 1] = e[i].val;
}
sort(a + 1, a + n, cmp);
int ans = inf;
for(int i = 1; i <= m; i++)
ans = min(ans, a[i] + a[2 * m - i + 1]);
cout << ans << '\n';
}
} int main() {
n = read(), m = read();
int flag = 1, f = 1;
for(int i = 1; i < n; i++) {
int u = read(), v = read(), w = read();
add(u, v, w);
add(v, u, w);
if(u != 1) flag = 0;
if(v != u + 1) f = 0;
sum += w;
}
if(flag) {
subtask3::solve();
}
else if(f){
subtask1::solve();
}
else {
subtask2::solve();
}
return 0;
}

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

#include <bits/stdc++.h>
using namespace std; inline int read() {
char c = getchar();
int x = 0, f = 1;
for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
return x * f;
} const int N = 50011;
const int inf = 0x3f3f3f3f;
int a[N], n, m, cnt, head[N], ans, up; struct node {
int to, nxt, val;
} e[N << 1]; multiset<int> s[N];
multiset<int>::iterator it; inline void add(int from, int to, int w) {
e[++cnt].to = to;
e[cnt].val = w;
e[cnt].nxt = head[from];
head[from] = cnt;
} int dfs(int x, int fa, int k) {
s[x].clear();
int w;
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(y == fa) continue;
w = dfs(y, x, k) + e[i].val;
if(w >= k) ans++;
else s[x].insert(w);
}
int maxn = 0;
while(!s[x].empty()) {
if(s[x].size() == 1) {
return max(maxn, *s[x].begin());
}
it = s[x].lower_bound(k - *s[x].begin());
if(it == s[x].begin() && s[x].count(*it) == 1) it++;
if(it == s[x].end()) {
maxn = max(maxn, *s[x].begin());
s[x].erase(s[x].find(*s[x].begin()));
} else {
ans++;
s[x].erase(s[x].find(*it));
s[x].erase(s[x].find(*s[x].begin()));
}
}
return maxn;
} int dfs1(int x,int fa) {
int sum1 = 0, sum2 = 0;
for(int i = head[x], y; i; i = e[i].nxt) {
y=e[i].to;
if(y == fa) continue;
sum2 = max(sum2, dfs1(y, x) + e[i].val);
if(sum1 < sum2) swap(sum1, sum2);
}
up = max(up, sum1 + sum2);
return sum1;
} int check(int k) {
ans = 0;
dfs(1, 0, k);
if(ans >= m) return 1;
return 0;
} int main() {
n = read(), m = read();
for(int i = 1; i < n; i++) {
int u = read(), v = read(), w = read();
add(u, v, w);
add(v, u, w);
}
dfs1(1, 0);
int l = 1, r = up, mid;
while(l < r) {
mid = (l + r + 1) >> 1;
if(check(mid)) l = mid;
else r = mid - 1;
}
cout << l << '\n';
}

洛谷 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. [SpingBoot guides系列翻译]Redis的消息订阅发布

    Redis的消息 部分参考链接 原文 CountDownLatch 概述 目的 这节讲的是用Redis来实现消息的发布和订阅,这里会使用Spring Data Redis来完成. 这里会用到两个东西, ...

  2. (三十四)golang--接口

    golang的多态特性主要体现在接口上: 主要优势:高内聚低耦合: package main import ( "fmt" ) type usb interface { start ...

  3. 获取主机信息,网络信息AIP,getsockname,getpeername,getservbyname,getservbyport,inet_ntop,inet_pton

    获取主机信息 1.ip地址转换,主机字节序 <---> 网络字节序 #include <arpa/inet.h> int inet_pton(int af, const cha ...

  4. LeetCode 61:旋转链表 Rotate List

    ​给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数. Given a linked list, rotate the list to the right by k pla ...

  5. linux不同服务器SSH连接与数据传送

    linux不同服务器通过SSH连接 SCP 命令进行数据传送 1. 安装scp yum install -y openssh-client 2.命令 复制文件(本地>>远程):scp /h ...

  6. vue+element 动态表单验证

    公司最近的项目有个添加动态表单的需求,总结一下我在表单验证上遇到的一些坑. 如图是功能的需求,这个功能挺好实现的,但是表单验证真是耗费了我一些功夫. vue+element在表单验证上有一些限制,必须 ...

  7. jQuery 源码分析(二) 入口模块

    jQuery返回的对象本质上是一个JavaScript对象,而入口模块则可以保存对应的节点的引用,然后供其它模块操作 我们创建jQuery对象时可以给jQuery传递各种不同的选择器,如下: fals ...

  8. Type Erasure with Pokemon---swift的类型擦除

    我感觉这个是swift的设计缺陷. 类型擦除:解决泛型类型作为公用类型的问题 是抽象的公用机制的一种实现方式. 1)类型擦除并不能解决类型不一致的兼容问题,只能解决类似继承一致性的兼容问题. 2)擦除 ...

  9. DLT645 1997 协议解析

    源码下载  -> 提取码 QQ:505645074 DLT645.zip 工具 源码 规约解析 DL/T645-07: 数据帧格式: 注意事项: (1)前导字节-一般在传输帧信息前,都要有0~4 ...

  10. python 提取整个 HTML 节点

    有的时候,需要把整个 HTML 节点原封不动地取下来,也就是包括节点标签.节点内容,甚至也包括内容中的空格.各种特殊符号等等. 假设已获取到页面源码,并将其保存在变量 src 中.则可有代码如下: f ...