正题

题目链接:https://www.luogu.org/problemnew/show/P5021


题目大意

一棵树找mmm条不重边路径使得最短的那条最长。


解题思路

首先最小的最大显然二分一下答案。之后问题转换为找最多条长度不小于midmidmid的路径。

如果dpdpdp的话需要二维,显然不能胜任本题。

那我们考虑贪心,一旦有长度不小于kkk的我们马上统计入答案,这样就可以节省掉dpdpdp的一维。现在我们的问题就是在一个交界点时对于每条子节点的路径,要么直接结束那条路径,要么往上连接,要么子节点之间连接。

那我们考虑如果一条传上来的路径长度valival_ivali​

若vali≥midval_i\geq midvali​≥mid那么直接结束改路径。
若vali&lt;midval_i&lt;midvali​<mid那么优先考虑连接子节点,因为往上传只能传一条,所以最大贡献为111,但是子节点之间连接的话贡献也为111。

那我们开一个平衡树或multisetmultisetmultiset(我是用multisetmultisetmultiset)储存所有vali&lt;midval_i&lt;midvali​<mid的值。每次取出最小的valminval_{min}valmin​并在剩下的中寻找一个valk≥mid−valminval_k\geq mid-val_{min}valk​≥mid−valmin​中最小的一个于其匹配。

然后在找没有匹配中最大的那个向上传就好了。


codecodecode

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
const int N=50100;
struct node{int to,next,w;
}a[N*2];
multiset<int> s[N];
multiset<int>::iterator it;
int n,m,tot,ans,k,l,r,sum;
int ls[N];
void addl(int x,int y,int z)
{a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=z;
}
int dfs(int x,int fa)
{for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa) continue;int val=dfs(y,x)+a[i].w;if(val>=k) ans++;else s[x].insert(val);}int up=0;while(!s[x].empty()){int val=*s[x].begin();if(s[x].size()==1){s[x].erase(s[x].find(val));return max(up,val);}it=s[x].lower_bound(k-val);if(it==s[x].end()) up=max(up,val);else{if(it==s[x].begin()&&s[x].count(*it)==1) it++;ans++;s[x].erase(s[x].find(*it));}s[x].erase(s[x].find(val));}return up;
}
bool check(int x)
{k=x;ans=0;dfs(1,1);if(ans>=m) return true;return false;
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<n;i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);addl(x,y,z);addl(y,x,z);sum+=z;}l=0;r=sum/m+1;while(l<=r){int mid=(l+r)/2;if(check(mid)) l=mid+1;else r=mid-1;}printf("%d",r);
}

P5021-赛道修建【平衡树,贪心,二分答案】相关推荐

  1. 数学题 贪心+二分答案

    Description 现在有两个数组 AA 和 BB, 分别包含 xx 与 yy 个元素. 定义一个新的数组 CC, CC 中包含 x×yx×y 个元素,为 AA 中所有元素除以 BB 中所有元素. ...

  2. P5021 赛道修建

    题目描述 C 城将要举办一系列的赛车比赛.在比赛前,需要在城内修建 m 条赛道. C 城一共有 n 个路口,这些路口编号为 1,2,-,n,有 n−1条适合于修建赛道的双向通行的道路,每条道路连接着两 ...

  3. 洛谷3933 Chtholly Nota Seniorious 二分答案+贪心

    题目链接 题意 给你一个N*M的矩阵 (N,M <=2000)  把他分成两部分 使两部分的极差较大的一个最小  求这个最小值.然后分矩阵的要求是:每个部分内部的方块之间,可以通过上下左右相互到 ...

  4. NOIP2018洛谷P5021:修建赛道

    没有证明的贪心就是乱搞 解析 把标签写在题面上的一道题- 显然要二分答案然后看能不能分出来m个 关键策略是每个结点内部尽可能的多匹配的前提下,给父亲传一个最大的 这不纪念品分组? 然后我就无脑的敲了个 ...

  5. 【BZOJ3048】Cow lineup,贪心+队列维护(或二分答案)

    传送门(权限题) 题面: 3048: [Usaco2013 Jan]Cow Lineup Time Limit: 2 Sec Memory Limit: 128 MB Submit: 121 Solv ...

  6. [HNOI2006]公路修建问题 ——二分答案+krukal(蒟弱个人总结)

    题目链接 文章目录 题意: 题解: AC代码 题意: 题目要求我们在n个景点之间建立n-1条公路,在花费尽量少的情况下至少有k条一级公路,求花费最多的一条公路的最小花费 题解: 二分答案+kruska ...

  7. CodeVS1725 探险 【二分答案】【贪心】

    [题目描述] 有编号为1至n的n个同学一起去探险,现在把他们分成k个小组,每个小组完成一项探险任务.分组时,如果第i人与第j人分在同一组(i < j),则他们之间的所有人(第i+1,i+2,-, ...

  8. NOIP2018·赛道修建

    初见安~本狸参加了2018年的NOIP,然后到现在[看题解]才能过Day1 T3--tcl--QwQ 本篇题解及代码有参考洛谷题解. 本篇夹带了对于二分深切的痛恨.请自行忽略. 传送门:洛谷 P502 ...

  9. NOIP2018D1T3赛道修建

    题目描述 一道让人受益匪浅的树形DP+贪心二分题 C 城将要举办一系列的赛车比赛.在比赛前,需要在城内修建m条赛道. C 城一共有n个路口,这些路口编号为1,2,-,n,有 n-1 条适合于修建赛道的 ...

最新文章

  1. 解决memcached不能远程访问的问题
  2. while用法_语法||由一句译文聊聊while的用法
  3. C++ 指向子类的指针转型为指向父类类型指针之后指向的对象地址不变
  4. python增删改查csv文件_【练习】Python第四次:实现对文件的增删改查
  5. prop()和attr()
  6. c#与api类型对照表
  7. [转]网易云音乐Android版使用的开源组件
  8. 2013B题碎纸片拼接
  9. SSM中拦截器和过滤器
  10. 了解局域网和广域网的概念差异
  11. scan函数函数用法详解
  12. 国产ADAS“再”突围
  13. Android S 默认WIFi 热点名称
  14. python38_python 并发编程
  15. c++/c/java数据结构--队列
  16. 把路由器变成音乐播放器和网络收音机,支持摇控
  17. 【单片机毕业设计】【mcuclub-jj-015】基于单片机的风扇的设计
  18. [翻译]现代java开发指南 第二部分
  19. 风速Weibull分布和光伏Beta分布的参数拟合方法
  20. 页面可用性之浏览器默认字体与CSS中文字体

热门文章

  1. python新手入门项目推荐_推荐:一个适合于Python新手的入门练手项目
  2. java蛮力法背包问题_[算法课]五种蛮力法解决01背包问题
  3. 数据结构——交换左右子树
  4. java获取jsp对象的属性_java-从jsp el中的对象获取布尔属性
  5. mysql权限create细化_mysql权限精细化分配-阿里云开发者社区
  6. 两数、三数、四数之和相关题目(Leetcode题解-Python语言)
  7. [SpringBoot2]welcomefavicon
  8. C++实现五子棋小游戏
  9. 对象的多数组表示(不一样的链表-多数组表示链表)
  10. python帮助系统函数_【Python】【基础知识】【内置函数】【help的使用方法】