首页 > 其他分享 >P10838 『FLA - I』庭中有奇树

P10838 『FLA - I』庭中有奇树

时间:2024-08-07 15:39:29浏览次数:11  
标签:dis1 传送 奇树 val 庭中 auto int FLA now

原题链接

获取题意

1.只能传送一次。

2.走树边没有限制。

3.只能传送至非相邻节点

4.路径一定是如下形式:

  • \(S\to x \to T\) 其中要么 \(x\to T\) 传送要么 \(S\to x\) 传送

  • \(S\to x \to y \to T\) 其中 \(x\to y\) 传送

  • \(S\to T\) 要么直接传送,要么全程走树边

分析

我们发现,如果传送,那么每一组传送对应的最短路径唯一的。

因此,我们可以遍历所有传送起点 \(x\) 和传送终点 \(y\),计算 \(dis[S][x]\) 和 \(dis[y][T]\)

然后累加上代价取第 \(m+1\) 小,时间复杂度 \(O(n^2)\)

考虑优化。

由于传送的代价都是一样的,因此求第 \(m+1\) 小的传送最短路径等价于求第 \(m+1\) 小的 \(dis[S][x]+dis[y][T]\)

我们预处理所有点到 \(S\) 和 \(T\) 的距离,排好序,将排好序的数组分别记作 \(a\) 和 \(b\)

该问题就变成了取所有 \(a_i+b_j\) 中的第 \(m+1\) 小

这是一个经典的问题,我们可以用堆处理

时间复杂度 \(O(m\cdot log n)\)

再次考虑优化。

我们换个角度思考,给定一个值,求有多少 \(a_i+b_j\) 比它小,怎么求?

这又是一个经典的问题,我们可以用双指针求出 ,这样我们只需要二分查找这个值就可以了

时间复杂度 \(O(n\cdot logn)\)

注意细节:也可以不传送,也可以走被封锁的路

code

#include<bits/stdc++.h>
using namespace std;

#define int long long

struct node
{
    int to, val;
};
vector<node> G[200005];

struct fresh
{
    int id, val;
} dis1[200005], dis2[200005], dis3[200005], dis4[200005];

void dfs1(int now, int fa, int val)
{
    dis1[now].val = val;
    dis1[now].id = now;

    dis3[now].val=val;
    dis3[now].id=now;

    for(auto next : G[now])
    {
        auto [to, len] = next;
        if(to == fa) continue;
        dfs1(to, now, val + len);
    }
}

void dfs2(int now, int fa, int val)
{
    dis2[now].val = val;
    dis2[now].id = now;

    dis4[now].val=val;
    dis4[now].id=now;
    for(auto next : G[now])
    {
        auto [to, len] = next;
        if(to == fa) continue;
        dfs2(to, now, val + len);
    }
}

struct unit
{
    int val, x, y;
    bool operator < (const unit &c) const
    {
        return c.val < val;
    }
};
const int inf = 1e9;

int n, m, k, s, t;

bool check(int x)
{
    int it2 = n;
    int sum = 0;
    for(int i = 1; i <= n; i++)
    {
        while(it2 && dis2[it2].val + dis1[i].val > x) it2--;
        sum += it2;
        if(!it2) break;

        for(auto next : G[dis1[i].id])
        {
            if(dis1[i].val + dis4[next.to].val <=x) sum--;//相邻节点无法传送
        }
        if(dis1[i].val + dis4[dis1[i].id].val <= x) sum--;
    }
    return sum>=m+1;
}

void solve()
{
    cin >> n >> m >> k >> s >> t;

    for(int i = 1; i < n; i++)
    {
        int x, y, w;
        cin >> x >> y >> w;
        G[x].push_back({y, w});
        G[y].push_back({x, w});
    }

    dfs1(s, s, 0);
    dfs2(t, t, 0);

    int ans = dis1[t].val; // 不传送,直接走树边

    sort(dis1 + 1, dis1 + 1 + n, [](auto b, auto c) { return b.val < c.val; });
    sort(dis2 + 1, dis2 + 1 + n, [](auto b, auto c) { return b.val < c.val; });

    ans=min(ans,dis1[1].val+dis2[1].val+(m?inf:k));//直接传送,不走树边

    int l = 0, r = 2e14;
    while(l + 1 < r)
    {
        int mid = (l + r) / 2;
        if(check(mid)) r = mid;
        else l = mid;
    }

    ans = min(ans, r + k);//传送和树边都走

    cout << ans << '\n';
}

signed main()
{
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int TT = 1;
    // cin >> TT;
    while(TT--) solve();
    return 0;
}

标签:dis1,传送,奇树,val,庭中,auto,int,FLA,now
From: https://www.cnblogs.com/pure4knowledge/p/18347141

相关文章

  • python+flask计算机毕业设计社区居民信息管理系统 (程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着城市化进程的加快,社区居民信息管理成为社区管理的重要组成部分。传统的社区管理方式存在信息更新不及时、管理效率低下等问题,难以满足......
  • Flask基础教程(第一阶段)
    目录Flask基础教程第一部分:Flask概述1.1了解Flask1.2Flask的优缺点分析1.3学习Flask的历史与背景第二部分:环境准备2.1Python环境2.2虚拟环境使用`venv`使用`conda`2.3Flask安装第三部分:创建第一个Flask应用3.1创建项目目录3.2编写基本的应用结构和第一个视图......
  • 使用 Flask 和 Yolov2 在 uLong32 中使用区域指针检测 2024 年奥林匹克数据集中的浮动
    你好StackOverflow!!!c:我正在使用#Yolov2和embedded#CVSSfordetecting浮动UIeleme#any视频对象实例中的ntse;在eexampl......
  • flash测试
    /*正点原子STM32F407最小系统板STM32F407ZGT6168MHzFlashsize1024KbytesRAMsize192KB*/include"main.h"include<string.h>include"systick.h"include"led.h"include"key.h"include"timer2.h"include&......
  • lambda 中 map 和 flatMap 的区别
    lambda中map和flatMap的区别 https://blog.csdn.net/weixin_52772307/article/details/128944511 总结:当我们需要将具有层级结构的数据展平时,也就是将多层数据转换为单层数据操作时,我们可以使用flatMap方法。如果我们只是简单的对流中的数据计算或者转换时,可以使用......
  • 【优秀python大屏】基于python flask的广州历史天气数据应用与可视化大屏
    摘要气象数据分析在各行各业中扮演着重要的角色,尤其对于农业、航空、海洋、军事、资源环境等领域。在这些领域中,准确的气象数据可以对预测未来的自然环境变化和采取行动来减轻负面影响的决策起到至关重要的作用。本系统基于PythonFlask框架,通过对气象数据的分析和处理来提供......
  • 003.flask与Mysql的连接以及增删改查
    目录Flask与Mysql的连接以及在Flask中对数据库进行增删改查1.创建文件并且配置2.flask与Mysql数据库进行连接以及检测是否连接成功3.创建一个类对象User以及将属性添加到数据库中4.在flask中进行数据库的增删改查5.总结Flask与Mysql的连接以及在Flask中对数据库进行增删改查p......
  • 003.flask与Mysql的连接以及增删改查
    Flask与Mysql的连接以及在Flask中对数据库进行增删改查python解释器:3.8.3版本flask==2.2.2版本flask_sqlalchemy=3.1.1flask_migrate==4.0.71.创建文件并且配置创建一个大文件在该文件中进行创建static(静态),templates(动态文件),app.py文件将大文件移到vsc......
  • FLAC库的编译及应用
    简介FLAC是一种针对声音文件的无损压缩算法。压缩比略低于AAC,但是压缩和解压的速度很理想。使用FLAC压缩的无损音乐,体积将比没有经过压缩的无损音乐小很多(取决于音乐的平均音量。通常体积能减少到原文件的50%左右)。相比较MP3有损压缩格式而言,FLAC能保留100%的音质。对......
  • 洛谷-P10837 『FLA - I』云音泛
    Abstract传送门这题是线段树+离散化的典型例子。Idea题目要求我们求出在至多只改变一朵花种植时间的情况下,最多有多长的时间是有且只有一朵花开放的。种花可以视为给起始时间到中止时间的区间+1,挖走一朵花,只用在原来的起始时间到中止时间的区间-1,即可,自然的想到用线段树去......