Luogu P4524 Ceste 题解
题目链接:\(\texttt{Luogu P4524 Ceste}\)
简化题意
给定一个有 \(n\) 个点 \(m\) 条边的无向图。每条边的边权为一个二元组 \((a, b)\),求以 \(1\) 为原点的最短路。
其中 \(a\) 到 \(b\) 的路径权值记为 \(\sum{a} \times \sum{b}\) 。
题目分析
最短路。
考虑单源最短路(这里说的是 dijkstra )的步骤:找到一个有效的点 \(a\) ,然后对它周围的点进行遍历,如果满足三角不等式 (\(d_a + w_i < d_b\)),那么更新 \(b\) 且入优先队列。
但是对于这道题,我们发现,我们并不知道哪些点会满足三角形不等式。换言之,我们不知道当前这个点是否应该入队。但是我们可以发现下面的性质:
对于点 \(a\),设可以到达 \(a\) 的路径集合为 \(S\) ,当前有到 \(a\) 的路径长度 \((d_a, d_b)\)。
\(\exists (S_a, S_b), S_a < d_a, S_b < d_b\),则 \((d_a, d_b)\) 一定不满足三角不等式。
\(\forall(S_a, S_b), S_a > d_b, S_b > d_b\),则 \((d_a, d_b)\) 一定满足三角不等式。
这样,我们可以对每个点搞一个 set,在里面存上每个到这个点的路径权值。然后每当得到一个新的长度,就去里面查一查,看看满不满足即可。
感觉复杂度有点玄学,可能是因为数据太弱了。如果数据加强了,我立即删题解。
参考代码
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <ctime>
#include <set>
#define itset set<PLL>::iterator
using namespace std;
using LL = long long;
using PII = pair<int, int>;
using PLL = pair<LL, LL>;
const int N = 2010, M = N << 1;
const LL INF = 1e12;
LL dist[N]; int n, m;
set<PLL> s[N];
bool st[N];
namespace Edges {
int h[N], e[M], ne[M], idx; PLL w[M];
void add(int a, int b, LL w1, LL w2) {
e[ ++ idx] = b, ne[idx] = h[a], h[a] = idx;
w[idx] = {w1, w2};
}
} using namespace Edges;
struct Node {
int ver; LL a, b;
bool operator < (const Node &tmp)const {
return tmp.a * tmp.b < a * b;
}
};
bool check(int u, LL a, LL b) {
itset it = s[u].upper_bound({a, b});
if (it != s[u].begin()) {
it -- ;
if (it -> second < b) return false;
}
return true;
}
void dij() {
priority_queue<Node, vector<Node>> q;
fill(dist + 1, dist + n + 1, INF);
s[1].insert({0, 0}); dist[1] = 0;
q.push({1, 0, 0});
while (q.size()) {
auto t = q.top(); q.pop();
int ver = t.ver, a = t.a, b = t.b;
for (int i = h[ver]; i; i = ne[i]) {
int j = e[i];
if (!check(j, a + w[i].first, b + w[i].second)) continue;
s[j].insert({a + w[i].first, b + w[i].second});
dist[j] = min(dist[j], (a + w[i].first) * (b + w[i].second));
q.push({j, a + w[i].first, b + w[i].second});
}
}
}
int main() {
scanf("%d%d", &n, &m);
while (m -- ) {
int a, b; LL w1, w2;
scanf("%d%d%lld%lld", &a, &b, &w1, &w2);
add(a, b, w1, w2), add(b, a, w1, w2);
}
dij();
for (int i = 2; i <= n; i ++ )
printf("%lld\n", dist[i] == INF ? -1 : dist[i]);
return 0;
}
Luogu P4524 Ceste 题解的更多相关文章
- 【luogu P3946 ことりのおやつ】 题解
题目链接:https://www.luogu.org/problemnew/show/P3946 交好几遍是因为虽然能过一直有提醒..强迫症qwq #include <bits/stdc++.h ...
- Luogu P2210 Haywire 题解
其实这题吧...有一种玄学解法 这题的要求的就是一个最小化的顺序 那么,我们就不进想到了一种显然的写法 就是random_shuffle 什么?这不是乱搞的非正解吗 然而,正如一句话说的好 一个算法, ...
- [Luogu P4178]Tree 题解(点分治+平衡树)
题目大意 给定一棵树,边带权,问有多少点对满足二者间距离$\leq K$,$n \leq 40000$. 题解 点分治专题首杀!$Jackpot!$ (本来看着题意比较简单想捡个软柿子捏,结果手断了… ...
- [火星补锅] 水题大战Vol.2 T1 && luogu P1904 天际线 题解 (线段树)
前言: 当时考场上并没有想出来...后来也是看了题解才明白 解析: 大家(除了我)都知道,奇点和偶点会成对出现,而出现的前提就是建筑的高度突然发生变化.(这个性质挺重要的,我之前没看出来) 所以就可以 ...
- Luogu P2158 仪仗队 题解报告
题目传送门 [题目大意] 给定一个n×n的点方阵,求站在左下角的点能看到的点数 注意同一条直线上只能看到一个点 [思路分析] 因为是一个方阵,所以可以对称地算,那么对于半个方阵,这里假设是左上的半个方 ...
- $Luogu P2029$ 跳舞 题解
一道不是十分水的\(dp\). 首先我们考虑\(dp\)方程的构造.起初我定义的状态是\(dp_{i,j}\)表示前\(i\)个格子,总共跳了\(j\)次的最大得分.但事实上它并不可以转移,因为我们不 ...
- Luogu P1342 请柬 题解
差不多是Dijkstra的裸题吧... 这道题可以分为来回两个阶段. 去的时候很简单,直接用一次Dijkstra,然后统计答案. 回来的时候就有些巧妙了,虽然表面上是每个点回到起点,但是何尝不可将其看 ...
- 「一本通 1.1 例 4」加工生产调度(贪心算法)(luogu P1248)题解
加工生产调度 题目描述 某工厂收到了 n n n 个产品的订单,这 n n n 个产品分别在 A.B 两个车间加工,并且必须先在 A 车间加工后才可以到 B 车间加工. 某个产品 i i i 在 A. ...
- luogu P3952 时间复杂度 模拟
题目链接 luogu P3952 时间复杂度 题解 直接模拟即可 注意不要直接return 我真是naive ...... 代码 #include<map> #include<sta ...
- luogu P4156 [WC2016]论战捆竹竿
传送门 官方题解(证明都在这) 神仙题鸭qwq 转化模型,发现这题本质就是一个集合,每次可以加上集合里的数,问可以拼出多少不同的数 首先暴力需要膜意义下的最短路,例题戳这 然后这个暴力可以优化成N^2 ...
随机推荐
- 一文带你实现云上部署轻量化定制表单Docker
本文分享自华为云社区 <[华为云云耀云服务器L实例评测|云原生]自定制轻量化表单Docker快速部署云耀云服务器 | 玩转华为云>,作者:计算机魔术师. 华为云的云耀云服务器L实例备受推崇 ...
- std::for_each易忽略点
以下代码为修改vector内部的每一个元素,使其每个元素大小变为原来的平方. std::vector v1{1, 2, 4, 2}; std::for_each(begin(v1), end(v1), ...
- Go 语言的前生今世与介绍
Go 语言的前生今世与介绍 目录 Go 语言的前生今世与介绍 一. Go 语言的发展 1.1 Go 语言是如何诞生的? 1.2 Go语言的早期团队和演进历程 1.3 Go语言正式发布并开源 1.4 G ...
- Windows下VC++编译器32位memcpy、memmove函数汇编代码详解
整理者:赤勇玄心行天道 QQ号:280604597 微信号:qq280604597 QQ群:511046632 博客:www.cnblogs.com/gaoyaguo blog.csdn.net/c ...
- 记一次服务器Cuda驱动崩溃修复过程
基本过程 今天实验室师兄在服务器运行深度学习训练时候得到报错CUDA initialization: Unexpected error from cudaGetDeviceCount()疑似Cuda与 ...
- ansible-playbook应用
ansible-playbook剧本: 如上使用Ad-hoc方式点对点命令执行,可以管理远程主机,如果服务器数量很多,配置信息比较多,还可以利用ansible playbook编写剧本.从而以非常简单 ...
- powershell 7 初体验
支持枚举定义,类定义\类继承\接口继承,不支持接口定义\泛型类定义\泛型函数定义,但是作为shell脚本已经相当让人惊喜了, 基本逻辑可以直接套用C#语法格式 # enum_sample/main.p ...
- 后缀自动机 (SAM) 的构造及应用
cnblogs 怎么又炸了. 为什么又可爱又强的 xxn 去年 9 月就会的科技樱雪喵现在还不会呢 /kel. 感觉 SAM 的教程已经被前人写烂了啊.那就写点个人学习过程中对 SAM 的理解. 参考 ...
- 数据结构-线性表-单循环链表(使用尾指针)(c++)
目录 单循环链表 说明 注意 (一)无参构造函数 (二)有参构造函数 (三)析构函数 (四)获取长度 (五)打印数组 (六)获取第i个元素的地址 (七)插入 (八)删除 (九)获取值为x的元素的位置 ...
- 一篇文章玩透awk
安装新版本gawk awk有很多种版本,例如nawk.gawk.gawk是GNU awk,它的功能很丰富. 本教程采用的是gawk 4.2.0版本,4.2.0版本的gawk是一个比较大的改版,新支持的 ...