赛道修建

题目描述

C 城将要举办一系列的赛车比赛。在比赛前,需要在城内修建 mm 条赛道。

C 城一共有 nn 个路口,这些路口编号为 1,2,…,n1,2,…,n,有 n-1n−1 条适合于修建赛道的双向通行的道路,每条道路连接着两个路口。其中,第 ii 条道路连接的两个路口编号为 a_iai? 和 b_ibi?,该道路的长度为 l_ili?。借助这 n-1n−1 条道路,从任何一个路口出发都能到达其他所有的路口。

一条赛道是一组互不相同的道路 e_1,e_2,…,e_ke1?,e2?,…,ek?,满足可以从某个路口出发,依次经过 道路 e_1,e_2,…,e_ke1?,e2?,…,ek?(每条道路经过一次,不允许调头)到达另一个路口。一条赛道的长度等于经过的各道路的长度之和。为保证安全,要求每条道路至多被一条赛道经过。

目前赛道修建的方案尚未确定。你的任务是设计一种赛道修建的方案,使得修建的 mm 条赛道中长度最小的赛道长度最大(即 mm 条赛道中最短赛道的长度尽可能大)

输入格式

输入文件第一行包含两个由空格分隔的正整数 n,mn,m,分别表示路口数及需要修建的 赛道数。

接下来 n-1n−1 行,第 ii 行包含三个正整数 a_i,b_i,l_iai?,bi?,li?,表示第 ii 条适合于修建赛道的道 路连接的两个路口编号及道路长度。保证任意两个路口均可通过这 n-1n−1 条道路相互到达。每行中相邻两数之间均由一个空格分隔。

输出格式

输出共一行,包含一个整数,表示长度最小的赛道长度的最大值。

输入输出样例

输入 #1复制

7 1
1 2 10
1 3 5
2 4 9
2 5 8
3 6 6
3 7 7

输出 #1复制

31

输入 #2复制

9 3
1 2 6
2 3 3
3 4 5
4 5 10
6 2 4
7 2 9
8 4 7
9 4 4

输出 #2复制

15

说明/提示

【输入输出样例 1 说明】

所有路口及适合于修建赛道的道路如下图所示:

道路旁括号内的数字表示道路的编号,非括号内的数字表示道路长度。 需要修建 11 条赛道。可以修建经过第 3,1,2,63,1,2,6 条道路的赛道(从路口 44 到路口 77), 则该赛道的长度为 9 + 10 + 5 + 7 = 319+10+5+7=31,为所有方案中的最大值。

【输入输出样例 2 说明】

所有路口及适合于修建赛道的道路如下图所示:

需要修建 33条赛道。可以修建如下 33条赛道:

  1. 经过第 1,61,6条道路的赛道(从路口 11 到路口77),长度为 6 + 9 = 156+9=15;
  2. 经过第5,2,3,85,2,3,8 条道路的赛道(从路口66 到路口 99),长度为 4 + 3 + 5 + 4 = 164+3+5+4=16;
  3. 经过第 7,47,4 条道路的赛道(从路口 88 到路口55),长度为 7 + 10 = 177+10=17。 长度最小的赛道长度为 1515,为所有方案中的最大值。

【数据规模与约定】

所有测试数据的范围和特点如下表所示 :

其中,“分支不超过 33”的含义为:每个路口至多有 33 条道路与其相连。 对于所有的数据, 2 ≤ n ≤ 50,0002≤n≤50,000, 1 ≤ m ≤ n-11≤m≤n−1, 1 ≤ a_i,b_i ≤ n1≤ai?,bi?≤n, 1 ≤ l_i ≤ 10,0001≤li?≤10,000。

玄学DFS第二弹:

其实MAP是能拿满分的,但是我代码找不到了。。。。。。

#include<cstdio>
#include<algorithm>
#include<cstring>

#define re register

using namespace std;

inline int read()
{
    int x=0;
    char ch=getchar();
    char c=ch;
    while(ch>‘9‘||ch<‘0‘)c=ch,ch=getchar();
    while(ch<=‘9‘&&ch>= ‘0‘)x=x*10+ch-‘0‘,ch=getchar();
    if(c==‘-‘)x=x*-1;
    return x;
}

inline void put(int x)
{
    if(x<0) putchar(‘-‘),x=~x+1;
    if(x>9) put(x/10);
    putchar(x%10+‘0‘);
}

const int N=5e5+5;

struct node{
    int y,z,nxt;
}a[N*2];

int len,last[N];

inline void add(int x,int y,int z){
    a[++len].y=y;
    a[len].z=z;
    a[len].nxt=last[x];
    last[x]=len;
}
int n,m,mid,now;

int f[N];

inline void dfs(int x,int fa){
    for(int k=last[x];k;k=a[k].nxt){
        if(a[k].y!=fa){
            dfs(a[k].y,x);
        }
    }
    int st[N],tp=0;
    for(int k=last[x];k;k=a[k].nxt){
        if(a[k].y!=fa){
            st[++tp]=f[a[k].y]+a[k].z;
        }
    }
    sort(st+1,st+tp+1);
    while(tp&&st[tp]>=mid){
        tp--;
        now++;
    }
    for(int i=1;i<=tp;++i){
        while(st[i]+st[tp]>=mid&&i<tp){
            now++;
            tp--;
            i++;
        }
    }
    if(tp){
        f[x]=st[tp];
    }
}
inline bool check(){
    now=0;
    dfs(1,0);
    if(now>=m){
        return true;
    }
    return false;
}
int main(){
    n=read();
    m=read();
    int l=0x3f3f3f3f,r=0,ans=0;
    for(int i=1;i<n;++i) {
        int x=read(),y=read(),z=read();
        add(x,y,z);add(y,x,z);r+=z;l=min(l,z);
    }
    while(l<=r){
        mid=(l+r)>>1;
        memset(f,0,sizeof(f));
        if(check()){
            ans=mid;
            l=mid+1;
        }
        else{
            r=mid-1;
        }
    }
    put(ans);
    putchar(‘\n‘);
    return 0;
}

原文地址:https://www.cnblogs.com/hrj1/p/11350900.html

时间: 2024-10-20 12:57:53

赛道修建的相关文章

P5021 赛道修建

题目描述 C 城将要举办一系列的赛车比赛.在比赛前,需要在城内修建 m 条赛道. C 城一共有 n 个路口,这些路口编号为 1,2,…,n,有 n−1条适合于修建赛道的双向通行的道路,每条道路连接着两个路口.其中,第 i 条道路连接的两个路口编号为ai? 和 bi?,该道路的长度为li?.借助这n−1 条道路,从任何一个路口出发都能到达其他所有的路口. 一条赛道是一组互不相同的道路e1?,e2?,…,ek?,满足可以从某个路口出发,依次经过 道路e1?,e2?,…,ek?(每条道路经过一次,不允

题解 luogu P5021 【赛道修建】

题解 luogu P5021 [赛道修建] 时间:2019.8.9 20:40 时间:2019.8.12 题目描述 C 城将要举办一系列的赛车比赛.在比赛前,需要在城内修建 \(m\) 条赛道. C 城一共有 \(n\) 个路口,这些路口编号为 \(1,2,\dots,n\),有 \(n-1\) 条适合于修建赛道的双向通行的道路,每条道路连接着两个路口.其中,第 \(i\) 条道路连接的两个路口编号为 \(a_i\) 和 \(b_i\),该道路的长度为 \(l_i\).借助这 \(n-1\) 条

2019.9.27 csp-s模拟测试53 反思总结

这个起名方式居然还有后续?! 为什么起名不是连续的?! T1想了半天,搞出来了,结果数组开小[其实是没注意范围].T2概率期望直接跳,后来翻回来写发现自己整个理解错了期望的含义[何].T3错误想到赛道修建结果来了个错误贪心. 关于T2破罐子破摔输出k居然骗了二十分这件事…… T1u: 一开始各种想偏,维护哪种值是奇数或偶数个,考虑每次操作影响哪些值变化…这些全都跑出来了. 大概过了一个世纪那么长,突然想着能不能直接优化操作的过程啊,然后对暴力进行钻研,终于开始想到差分. 然后觉着nq的复杂度过不

noip历年试题

noip2018 铺设道路 货币系统 赛道修建 一眼贪心.随便实现. 旅行 环套树枚举删除环上哪条边. 填数游戏 找规律,这谁会啊. 保卫王国 动态Dp,去问这位神仙. noip2017 小凯的疑惑 就是数论结论题,当然也可以找规律. 时间复杂度 原理都懂,大模拟. 逛公园 SPFA还没死.jpg 奶酪 宝藏 状压Dp. 列队 我太懒了直接Splay模拟. noip2016 玩具谜题 天天爱跑步 考虑一条链怎么做(随便做),然后树上同理. 换教室 组合数问题 蚯蚓 拿两个队列来归并. 愤怒的小鸟

「CF1039D」You Are Given a Tree

传送门 Luogu 解题思路 整体二分. 的确是很难看出来,但是你可以发现输出的答案都是一些可以被看作是关键字处于 \([1, n]\) 的询问,而答案的范围又很显然是 \([0, n]\),这不就刚好满足了整体二分的几个组成部分了吗. 那么我们要如何求出 \(mid\) 位置的解呢? 考虑 \(\text{DP}\) 我们很显然可以将子树中的点尽可能合并后再向父亲传递,所以我们对每一次DP的根节点分别记一个子树中的最大值,和一个非严格次大值,然后我们尝试合并这两个值,要是合并不了,就给答案加一

我爱OI(来自一个年老但是毫无成就的IOer的退役感言)

某盆终于退役了... 这可能是本博客的最后一篇文章了吧... 如果不,那就还有两个方向: 1.自己闲得无聊学学算法 2.当成自己的随笔博客不知道该干些什么了.AFO了. 然后呢?该扯点什么了?? 额说到这,想起来我们也学了4年OI了吧 从第一年的暑假,78人,坐在实验的大机房里,每人带一瓶冰块, 到第二年的50人,分布在沈老师的五个班里, 再到仅剩的20人,分布在一中二中, 渐渐的,只剩下9人依旧奋战在一线, 一次意外,我们的团队又少了一个人——bk201. 一路经历了多少? 四次集训,分布全国

ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 最小生成树 Kruskal算法

题目链接:ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 Building a Space Station Time Limit: 2 Seconds      Memory Limit: 65536 KB You are a member of the space station engineering team, and are assigned a task in the construction process of the statio

POJ 2421 Constructing Roads 修建道路 最小生成树 Kruskal算法

题目链接:POJ 2421 Constructing Roads 修建道路 Constructing Roads Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 19698   Accepted: 8221 Description There are N villages, which are numbered from 1 to N, and you should build some roads such that e

洛谷P1265 公路修建

P1265 公路修建 177通过 600提交 题目提供者该用户不存在 标签图论 难度普及+/提高 提交该题 讨论 题解 记录 最新讨论 long long类型赋值-1为什么… p党80的进 为什么不过啊... 题目描述 某国有n个城市,它们互相之间没有公路相通,因此交通十分不便.为解决这一“行路难”的问题,政府决定修建公路.修建公路的任务由各城市共同完成. 修建工程分若干轮完成.在每一轮中,每个城市选择一个与它最近的城市,申请修建通往该城市的公路.政府负责审批这些申请以决定是否同意修建. 政府审