原题链接:AT2434 JOI 公園 (JOI Park)

写完之后看到题解区的三分吓了一跳

分析与解答

由于最终答案与边权有关,所以不妨考虑判断一条边是否会对答案有贡献。

记 \(dis\) 表示以点 \(1\) 为源点的最短路径长度,那么答案可以表示为 \(X \times C + \sum\limits_{i=1}^{m} d_i\ [\max(dis_{a_i}, dis_{b_i}) \gt X]\),也就是说只有当一条道路两端点的最短路长度均大于当前 \(X\) 时,这条道路的才会对答案有贡献。

这一点是可以根据题目描述得到的。

然后注意到一个事实:虽然题目中说 \(X\) 可以取任意自然数,但是显然 \(X\) 取以点 \(1\) 为源点的一条最短路径长度时最优。显然易证·也就是说枚举 \(X\) 的值时只需要枚举 \(dis\) 数组即可。

所以我们只需要求出以点 \(1\) 为源点的最短路径长度,然后求出每一条边想要被计入答案所需要的最小 \(X\) 值,记为 \(val\),即 \(\max(dis_{a_i}, dis_{b_i})\),然后按照该值对边排序,最后按照枚举当前 \(val\) 计算答案即可。

形象地说,就是在对边进行排序只后,选用一条边 \(i\) 作为“分界点”,所有 \(val_j \gt val_i\) 的边 \(j\) 的边权都会计入答案,其他则不会。

记得开 long long

这里运用堆优化的 Dijkstra 算法求最短路,时间复杂度 \(\Theta(n \log n)\)

Code

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue> using namespace std; typedef long long ll;
typedef pair<long long,int> pli;
const int MAXN = 100010;
const int MAXM = 200010;
const ll INF = 0x3f3f3f3f3f3f3f3f; int n, m, c; struct edge1{
int u, v, w;
ll val; int ind;
bool operator<(const edge1 &o)const{return val < o.val;}
}a[MAXM];
struct edge{
int ne, to, w;
edge(int N=0,int T=0,int W=0):ne(N),to(T),w(W){}
}e[MAXM<<1];
int fir[MAXN], num = 0;
inline void join(int a, int b, int c)
{
e[++num] = edge(fir[a], b, c);
fir[a] = num;
} ll dis[MAXN];
bool vis[MAXN];
priority_queue<pli,vector<pli>,greater<pli> > h; inline void dijkstra(int s = 1)
{
for(int i=1;i<=n;i++)
dis[i] = INF, vis[i] = 0;
dis[s] = 0;
h.push(make_pair(dis[s], s));
while(!h.empty())
{
int u = h.top().second;
h.pop();
vis[u] = 1;
for(int i=fir[u];i;i=e[i].ne)
{
int v = e[i].to;
if(dis[v] > dis[u] + e[i].w)
{
dis[v] = dis[u] + e[i].w;
if(!vis[v]) h.push(make_pair(dis[v], v));
}
}
}
} int main()
{
ll sum = 0, ans = 0;
scanf("%d%d%d",&n,&m,&c);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
join(a[i].u, a[i].v, a[i].w);
join(a[i].v, a[i].u, a[i].w);
a[i].ind = i;
sum += a[i].w;
}
ans = sum;
dijkstra(1); // 求最短路
for(int i=1;i<=m;i++)
a[i].val = max(dis[a[i].u], dis[a[i].v]);
sort(a+1, a+m+1);
for(int i=1;i<=m;i++)
{
sum -= a[i].w;
ans = min(ans, sum+1ll*a[i].val*c);
// 枚举以一条边为分界点时的答案
}
printf("%lld\n",ans);
return 0;
}

JOI 公園 (JOI Park)的更多相关文章

  1. 【AT2434】JOI 公園 (JOI Park) 最短路+贪心

    题解 我的歪解 我首先想的是分治,我想二分肯定不行,因为它是没有单调性的. 我想了一下感觉它的大部分数据应该是有凸性的(例如\(y=x^2\)的函数图像),所以可以三分. 下面是我的三分代码(骗了不少 ...

  2. 洛谷 AT2434 JOI 公園 (JOI Park) 题解

    人生第一次AC黑题,我太感动了. 每日一题 day31 打卡 Analysis 先跑遍DJ,求出1到 i的最短路.得到每个点到 1号点的距离后,从小到大排序一遍,这时便可以枚举每个点到 1号点的距离修 ...

  3. csp-s 考前刷题记录

    洛谷 P2615 神奇的幻方 洛谷 P2678 跳石头 洛谷 P1226 [模板]快速幂||取余运算 洛谷 P2661 信息传递 LOJ P10147 石子合并 LOJ P10148 能量项链 LOJ ...

  4. 使用joi来验证数据模型

    我们用nodejs实现一些功能时,往往需要对用户输入的数据进行验证.然而,验证是一件麻烦的事情,很有可能你需要验证数据类型,长度,特定规则等等,在前端做表单验证时,我们常用的做法是使用正则,正则表达式 ...

  5. [Hapi.js] Request Validation with Joi

    hapi supports request validation out of the box using the joi module. Request path parameters, paylo ...

  6. joi库 学习笔记

    零.背景 node.js 应用中,req.query / req.body 传来的参数需要做 valication( 合法性验证 ) 一.安装 https://github.com/hapijs/jo ...

  7. JOI徽章

    [题目描述] 日本信息学奥赛委员会为了应援将要去台湾参加 IOI 的选手们,打算制作一面新的 JOI 旗帜 .JOI 旗帜为由 M 行 N 列的 M*N 个正方形组 成的图形,每个正方形里写有 J,O ...

  8. 第三方库文件Joi对数据进行验证的方法以及解决Joi.validate is not a function的问题

    Joi:javaScript对象的规则描述语言和验证器 1.npm install joi@14.3.1 2.建立joi.js文件 3.导入第三方包joi const Joi = require('j ...

  9. 卷积神经网络CNN全面解析

    卷积神经网络(CNN)概述 从多层感知器(MLP)说起 感知器 多层感知器 输入层-隐层 隐层-输出层 Back Propagation 存在的问题 从MLP到CNN CNN的前世今生 CNN的预测过 ...

  10. Fastify 系列教程一(路由和日志)

    介绍 Fastify是一个高度专注于以最少开销和强大的插件架构,为开发人员提供最佳体验的Web框架. 它受到了 Hapi 和 Express 的启发,是目前最快的 Node 框架之一. Fastify ...

随机推荐

  1. python 之用户自定义函数

    什么是函数? 函数无非就是将代码块进行封装,想用的时候拿来用,减少代码量,提高效率. 函数的定义 定义一个函数需要: 1.def关键字,def 后面空一格输入函数名称,函数命名时尽量简短,且具有意义, ...

  2. VUE 使用md5对用户登录密码进行加密传输

    VUE 使用md5对用户登录密码进行加密传输到数据库 前言 第一步 npm下载js-md5依赖包 第二步 引入js-md5 直接在需要使用md5加密的页面引入 全局挂载,将js-md5添加到vue原型 ...

  3. paozhu c++ web framework 框架原理

    paozhu c++ web framework 框架原理 paozhu c++ web framework 使用 asio 网络库,如果用动态库方式还要boost库. paozhu框架 使用两个线程 ...

  4. 为 ASPNETCORE 7 项目添加 Serilog

    本文将介绍如何为 ASP.NET Core 项目添加 Serilog. 添加 Serilog 首先,我们需要在项目中添加 Serilog 的 NuGet 包. dotnet add package S ...

  5. [python] 基于matplotlib_venn实现维恩图的绘制

    文章目录 VENN DIAGRAM(维恩图) 1. 具有2个分组的基本的维恩图 Venn diagram with 2 groups 2. 具有3个组的基本维恩图 Venn diagram with ...

  6. “It is required that your private key files are NOT accessible by others. This private key will be ignored.”

    Windows Terminal 通过密钥登录远程vps时提示: "It is required that your private key files are NOT accessible ...

  7. [C#]关于逆变与协变的基本概念和修饰符in与out的意义

    协变与逆变的概念 假如两个类型X和Y具有特殊关系,X类型的每个值都能转换成Y类型.我们将I<X>向I<Y>的转换称为协变转换.反之我们将I<Y>向I<X> ...

  8. 【项目实战】从零到一搭建Spring Boot整合Mybatis-plus

    前言 2023年想搭建一套属于自己的框架,做一个属于自己想法的项目.这些年工作中一直用公司已有的框架,以前有跟着学习视频搭建过,但自己真正动手搭建时发现问题还是很多,比如没有引入Mybatis-plu ...

  9. odoo资料

    https://www.cnblogs.com/smarttony/category/1484288.html

  10. 带你熟悉3种AQS的线程并发工具的用法

    摘要:AQS 的全称为(AbstractQueuedSynchronizer),AQS 是一个用来构建锁和同步器的框架,使用 AQS 能简单且高效地构造出应用广泛的大量的同步器. 本文分享自华为云社区 ...