洛谷 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. word设置标题1,标题2,标题3项目编号联动

    word经常要按层级显示标题,并且标题样式之间要联动 如: 设置办法: word内鼠标右键 2.选择项目符号和编号 3.选择一个样式并自定义 将级别链接到样式.选择对应标题样式即可实现联动.

  2. client-go客户端自定义开发Kubernetes及源码分析

    介绍 client-go 是一种能够与 Kubernetes 集群通信的客户端,通过它可以对 Kubernetes 集群中各资源类型进行 CRUD 操作,它有三大 client 类,分别为:Clien ...

  3. ROS机器人路径规划介绍--全局规划

    ROS机器人路径规划算法主要包括2个部分:1)全局路径规划算法:2)局部路径规划算法: 一.全局路径规划 global planner ROS 的navigation官方功能包提供了三种全局路径规划器 ...

  4. 『The Counting Problem 数位dp』

    The Counting Problem Description 求 [L,R]内每个数码出现的次数. Input Format 若干行,一行两个正整数 L 和 R. 最后一行 L=R=0,表示输入结 ...

  5. ELK 日志平台 For Windows

    一.Logstash 安装 1. 下载最新版本的logstash:  https://www.elastic.co/fr/downloads/logstash 下载zip格式的压缩包. 然后解压缩放到 ...

  6. C# 处理接口返回的XML格式数据

    using System.Xml; //引入命名空间 //模拟接口返回的数据 string str=@"<JZD_Message xmlns:xsd=""http: ...

  7. Java生鲜电商平台-供应链模块的设计与架构

    Java生鲜电商平台-供应链模块的设计与架构 说明:Java开源生鲜电商平台中供应链模块属于卖家的行为,也就是卖家如何管理他们自己的供应商,包括结算方式,压款方式,结算周期等等,超出了我这个B2B平台 ...

  8. SVN每日定时备份脚本

    SVN每日定时备份脚本: @ECHO off REM SVN安装目录 SET SVN_HOME="D:\Program Files\VisualSVNServer" REM 版本库 ...

  9. JavaScript全局属性和全局函数

    JavaScript全局属性和全局函数可以与所有内置JavaScript对象一起使用. JavaScript全局属性 属性 描述 Infinity 表示正/负无穷大的数值 NaN "Not- ...

  10. 学习shiro第一天

    shiro是一个强大而且易用的安全框架(主要包括认证和授权),它比spring security更加简单,而且它不依赖于任何容器,可以和许多框架集成. shiro的核心是安全管理器(SecurityM ...