洛谷 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. (二十二)golang--时间和日期相关函数

    时间的常量,可以获得指定时间单位 Unix和UnixNano   小例子:统计函数运行的时间:

  2. 我在生产项目里是如何使用Redis发布订阅的?(一)使用场景

    转载请注明出处! 导语 Redis是我们很常用的一款nosql数据库产品,我们通常会用Redis来配合关系型数据库一起使用,弥补关系型数据库的不足. 其中,Redis的发布订阅功能也是它的一大亮点.虽 ...

  3. centos6 升级Git版本

    操作步骤如下: yum remove -y git #卸载旧版本Git yum install -y tk zlib-devel openssl-devel perl cpio expat-devel ...

  4. 一个人的公众号,我写了1w+

    大家好,我是Bypass,一个人一直保持着写博客的习惯,为此维护了一个技术公众号,致力于分享原创高质量干货,写的内容主要围绕:渗透测试.WAF绕过.代码审计.应急响应.企业安全. 一直以来,我把它当成 ...

  5. Winform中实现设置ZedGraph的GraphPane的大小匹配ZedGraphControl

    场景 Winforn中设置ZedGraph曲线图的属性.坐标轴属性.刻度属性: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...

  6. 死磕Synchronized底层实现,面试你还怕什么?

    关于synchronized的底层实现,网上有很多文章了.但是很多文章要么作者根本没看代码,仅仅是根据网上其他文章总结.照搬而成,难免有些错误:要么很多点都是一笔带过,对于为什么这样实现没有一个说法, ...

  7. JavaScript Location 对象用法

    Location 对象 Location对象包含有关当前URL的信息.location对象是window对象的一部分,可以通过window.location属性访问. 注意:没有适用于location ...

  8. 【初识Spring】对象(Bean)实例化及属性注入(注解方式)

    通过xml的方式进行对象的实列化或属性注入或许有一些繁琐,所以在开发中常用的方式更多是通过注解的方式实现对象实例化和属性注入的. 开始之前 1.导入相关的包(除了导入基本的包还要导入aop的包): 创 ...

  9. 个人项目(WC.exe)(java)(基于图形界面)

    一.Github项目地址:https://github.com/Leungdc/ENhomework 二.PSP: PSP2.1 Personal Software Process Stages 预估 ...

  10. K3 主控台创建

    /*================================================== FFFFFF OOOO GGGG EEEEEE RRRR SSSS ###### FF OO ...