ABC270F 题解
思路
首先看到花最小代价使得所有点连通,果断转换成最小生成树问题。
接下来就要考虑怎么建图,首先陆地就正常连不用说,建机场和港口的代价貌似都是点权,考虑转成边权。因为一个点飞或者划船到另一个点要两重代价,所以若我们想让 \(u\) 和 \(v\) 建能飞过去的边,我们可以先从 \(u\) 建一条边权为 \(x[u]\) 的边到 \(t\),再从 \(t\) 建一条边权为 \(x[v]\) 的边到 \(v\)。
我们按照上面的思路让每个点都和其余 \(n-1\) 个点这样建边就能得到一张完全图。这样建图虽然在意义上是没有问题的,但是再跑最小生成树时会强制性把所有无关的中转点也选进去,导致代价重复计算,而且是完全图,边数达到 \(O(n^2)\) 级别,光建图就 TLE 了。
我们可以这样去想:我们可以多建两个大点,表示一整片天空,和一整片海。每个点都要对着海和天空连一条边(听起来怎么有点浪漫),边权为自己建机场和港口的代价。这样我们就可以实现我们刚才想达到的所有目的了。
为什么呢?首先看第一个目的,为了解决点权转边权,我们也用了中转站解决,而且只要多建 \(2n\) 条边。那这样也有个问题,也不是非要走天和走海,万一走普通边最优呢。为了解决这个问题我们可以直接暴力跑 4 次最小生成树——
只开车
只飞天和开车
只航海和开车
又飞天又航海又开车
这样就完美解决了。至于最重要的一点,为什么只用所有点连到天空和海不影响图的结构?因为图的本质就是一堆点集和一堆描述联通关系的边。我们看第一版建边思路,点集只有 \(O(n)\),但边数真的有必要这么多吗?
我们注意到每一个我们建的中转点连出去的点集都是一样的,因此有一个中转点就足够。而且对于每一个点,能达到的点和边权的状态都和有一个中转点的情况相同,所以没必要连成完全图,而是把属于这一类的所有边聚集到一个源点,将稠密图稀疏化,而且使得以前每个点能到达的点与边权的状态一样……
我们一般把这类 trick 叫做 建超级源点,聚集到的源点叫做 超级源点。当然这也只是超级源点的一种用法,之后更多好玩的用法大家可以多找点图论题找找,说不定那道题的题解也会是我写的。
实现
之后讲一下实现。也就是按上面的思路建 4 次边跑 4 次最短路,但有一些细节值得注意。
第 0 次跑最小生成树时,陆地上的边不一定能形成最小生成树,但是其他 3 次保证一定能形成最小生成树。
最多会有 \(3n\) 条边,数组要开够
做 4 次生成树要建 4 次边,而有些代码可以复用,可以使用一些模拟技巧缩短此题代码长度
代码
//
// main.cpp
// [ABC270F] Transportation
//
// Created by SkyWave Sun on 2023/11/30.
//
#include <iostream>
#include <algorithm>
#include <vector>
#include <numeric>
#include <climits>
using namespace std;
typedef long long ll;
const int N = 2e5 + 1;
struct dsu {
vector<int> fa;
void resize(int sz) {
fa.resize(sz + 1);
iota(fa.begin(), fa.end(), 0);
}
dsu() {
}
dsu(int sz) {
resize(sz);
}
int findFa(int pos) {
return pos == fa[pos] ? pos : fa[pos] = findFa(fa[pos]);
}
void mergeFa(int u, int v) {
fa[findFa(u)] = findFa(v);
}
bool same(int u, int v) {
return findFa(u) == findFa(v);
}
};
struct Edge {
int u, v, w;
bool operator < (const Edge &e) const {
return w < e.w;
}
};
Edge e[N * 3];//注意数组大小
ll kruskal(int n, int m) {
sort(e + 1, e + m + 1);
dsu d(n);
ll ans = 0;
int cnt = 0;
for (int i = 1; i <= m; ++i) {
if (!d.same(e[i].u, e[i].v)) {
d.mergeFa(e[i].u, e[i].v);
ans += e[i].w;
++cnt;
}
if (cnt == n - 1) {
break;
}
}
return cnt == n - 1 ? ans : LONG_LONG_MAX;//不能形成最小生成树时返回无穷大不对最后答案产生影响
}
int x[N], y[N];
int u[N], v[N], w[N];
int main(int argc, const char * argv[]) {
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) {
scanf("%d", &x[i]);
}
for (int i = 1; i <= n; ++i) {
scanf("%d", &y[i]);
}
for (int i = 1; i <= m; ++i) {
scanf("%d%d%d", &u[i], &v[i], &w[i]);
}
ll ans = LONG_LONG_MAX;
for (int i = 0; i < 4; ++i) {//类似状压枚举复用建边代码
int source = n/*超级源点编号*/, rear = 0;
if (i & 1) {
++source;/*天上边超级源点为 n + 1*/
for (int j = 1; j <= n; ++j) {
e[++rear] = {source, j, x[j]};
}
}//在 i = 1、 3 的时候建天上边
if (i & 2) {
++source;/*海上边超级源点为 n + 2*/
for (int j = 1; j <= n; ++j) {
e[++rear] = {source, j, y[j]};
}
}//在 i = 2、3 的时候建海上边
for (int j = 1; j <= m; ++j) {
e[++rear] = {u[j], v[j], w[j]};
}//i = 0、1、2、3 都要建陆地边
ans = min(ans, kruskal(source, rear));
}
printf("%lld\n", ans);
return 0;
}
ABC270F 题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
- JSOI2016R3 瞎BB题解
题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...
随机推荐
- SpringCloud学习 系列十、服务熔断与降级(1-简介)
系列导航 SpringCloud学习 系列一. 前言-为什么要学习微服务 SpringCloud学习 系列二. 简介 SpringCloud学习 系列三. 创建一个没有使用springCloud的服务 ...
- WebGPU光追引擎基础课:课程介绍
大家好~我开设了"WebGPU光追引擎基础课"的线上课程,从0开始,在课上带领大家现场写代码,使用WebGPU开发基础的光线追踪引擎 课程重点在于基于GPU并行计算,实现BVH构建 ...
- zzuli 1908
***做的时候判断当前位置为.的上下左右是否为*,如果全是改位置就改为*,如果四周中有为.,再DFS一下,其实就相当于把判断化为更小的子问题*** #include<iostream> # ...
- spring cloud gateway在使用 zookeeper 注册中心时,配置https 进行服务转发
本文为博主原创,转载请注明出处: 在spring cloud gateway 为 2.x 的版本的时候,可以通过引入 ribbon ,在进行过滤器 LoadBalancerClientFilter 进 ...
- maven开源仓库
在公司开发一般都用公司内部的maven仓库,但回家之后,就访问不了公司的网络,使用不了公司的maven仓库,只能使用开源的maven仓库. 在网上搜索和整理了几个比较好用的maven开源镜像仓库,记录 ...
- SpringMVC - 加载静态资源
静态资源过滤 spring-config.xml <!-- 3,(1)让Spring MVC不处理静态资源 .(2)加载静态资源,也称为资源过滤 --> <mvc:default-s ...
- [转帖]oracle 11g 分区表创建(自动按年、月、日分区)
https://www.cnblogs.com/yuxiaole/p/9809294.html 前言:工作中有一张表一年会增长100多万的数据,量虽然不大,可是表字段多,所以一年下来也会达到 1G ...
- 【转帖】32.MinorGC、MajorGC和FullGC的对比
目录 1.MinorGC.MajorGC和FullGC的对比 2.GC触发机制 1.MinorGC.MajorGC和FullGC的对比 1.JVM在进行GC的时候,并不是每次都是对新生代.老年代.永久 ...
- [转帖]mysql百万级性能瓶颈-数据库选型
项目中使用了mysql数据库,但数据量增长太快,不久到了百万级,很快又到表到了千万级,尝试了各种优化方式,最终效果仍难达到秒级响应,那么引发了我关于数据库选型到一些思考. 1.mysql的单表性能瓶颈 ...
- 我在京东做研发 | 揭秘支撑京东万人规模技术人员协作的行云DevOps平台
随着业务变化的速度越来越快各类IT系统的建设也越来越复杂大规模研发团队的管理问题日益突出如何提升研发效能成为时下各类技术团队面临的重要挑战 京东云DevOps专家将带您深入研发一线揭秘支撑京东集团万人 ...