《算法竞赛·快冲300题》每日一题:“最小生成树”

算法竞赛·快冲300题》将于2024年出版,是《算法竞赛》的辅助练习册。
所有题目放在自建的OJ New Online Judge。
用C/C++、Java、Python三种语言给出代码,以中低档题为主,适合入门、进阶。

文章目录

  • 题目描述
  • 题解
  • C++代码
  • Java代码
  • Python代码

最小生成树” ,链接: http://oj.ecustacm.cn/problem.php?id=1804

题目描述

【题目描述】
在平面中有n个点(xi,yi),两点之间的距离为欧几里得距离的平方。
求最小生成树的权重。
平面坐标满足:(0≤xi≤1000000,0≤yi≤10)
【输入格式】 输入第一行为正整数n,n不超过100000。
接下来n行,每行两个整数x和y,表示坐标点(x,y)。
【输出格式】 输出一个数表示答案。
【输入样例】

10
83 10
77 2
93 4
86 6
49 1
62 7
90 3
63 4
40 10
72 0

【输出样例】

660

题解

   本题差不多是一道最小生成树的模板题,但是需要处理好边。本题的任意两点间有边,边的总数量约为 n 2 / 2 n^2/2 n2/2,而n最大是 1 0 6 10^6 106 n 2 / 2 n^2/2 n2/2条边显然会超出空间限制。
   能否减少边的数量?注意到本题所有点的y坐标的限制是0≤yi≤10,这n个点的y坐标都在0和10之间。在平面上画11根横线;y=0,y=1,…,y=11,那么n个点都会在这11根线上。当处理到第i点时,只要把它和左边的11根线上的最近点连接,并且把它与右边的11根线上的最近点连接即可。这样得到的边,仍然会连通所有点,并且保留了最短的边。这样,每个点只需要连22个边,总边数只有22×n条。
   不过还可以简化,对每个点,只连它左边的11条边即可,不用连右边的边,请思考为什么。
   处理好边后,其他代码就是标准的最小生成树的模板。本题的边数不多,用代码比较简单的Kruskal算法编码。
【笔记】 最小生成树。

C++代码

  

#include<bits/stdc++.h>
using namespace std;
#define Mul(a) ((long long)(a) * (a))
const int N = 1e5 + 10;
typedef pair<int, int> Node;
int n, m;         //点、边
Node a[N];        //n个点的坐标
struct edge{int u, v;long long w;
}e[N * 22];           //边的数量。如果只连左边的11条边,这里改为N*11
bool cmp(edge a, edge b){ return a.w < b.w;}    //从小到大排序
void add_edge(int u, int v) {  //点u和点v连边m++;e[m].u = u;e[m].v = v;e[m].w = Mul(a[u].first - a[v].first) + Mul(a[u].second - a[v].second);
}
int s[N];//并查集
int find_set(int x){      //查询并查集,返回x的根if(x != s[x])s[x] = find_set(s[x]);     //路径压缩return s[x];
}
void kruskal(){for(int i = 1; i <= n; i++)  s[i] = i;    //并查集初始化sort(e + 1, e + 1 + m,cmp);               //边排序long long ans = 0;for(int i = 1; i <= m; i++){              //从小到大遍历边,加入到最小生成树int u = find_set(e[i].u), v = find_set(e[i].v);if(u==v) continue;                    //产生了圈,丢弃else  s[u] = v, ans += e[i].w;}cout<<ans<<endl;
}
int Last[15];
int main(){cin >> n;for(int i = 1; i <= n; i++) cin >> a[i].first >> a[i].second;sort(a + 1, a + 1 + n);                    //对点排序。实际是对x从小到大排序//每个点往每行的左边最近点连边for(int i = 0; i <= 10; i++)   Last[i] = 0;for(int i = 1; i <= n; i++) {for(int y = 0; y <= 10; y++)if(Last[y])   add_edge(i, Last[y]);Last[a[i].second] = i;}//每个点往每行的右边最近点连边。可以省略/* for(int i = 0; i <= 10; i++)Last[i] = 0;for(int i = n; i >= 1; i--) {for(int y = 0; y <= 10; y++)if(Last[y])   add_edge(i, Last[y]);Last[a[i].second] = i;}*/kruskal();return 0;
}

Java代码

import java.util.*;public class Main {static class Node implements Comparable<Node>{int x, y;Node(int x, int y) {this.x = x;this.y = y;}public int compareTo(Node o) {return Integer.compare(this.x, o.x);}}static class Edge implements Comparable<Edge>{int u, v;long w;Edge(int u, int v, long w) {this.u = u;this.v = v;this.w = w;}public int compareTo(Edge o) {return Long.compare(this.w, o.w);}}static final int N = 1_00_005;static Node[] a = new Node[N];static Edge[] e = new Edge[N * 11];static int[] s = new int[N];static int[] Last = new int[15];static int n, m;static long mul(int a) {  return (long)a * a; }static void addEdge(int u, int v) {m++;e[m] = new Edge(u, v, mul(a[u].x - a[v].x) + mul(a[u].y - a[v].y));}static int findSet(int x) {if (x != s[x])s[x] = findSet(s[x]);return s[x];}static void kruskal() {for (int i = 1; i <= n; i++) s[i] = i;Arrays.sort(e, 1, m + 1);long ans = 0;for (int i = 1; i <= m; i++) {int u = findSet(e[i].u), v = findSet(e[i].v);if (u == v) continue;s[u] = v;ans += e[i].w;}System.out.println(ans);}public static void main(String[] args) {Scanner sc = new Scanner(System.in);n = sc.nextInt();for (int i = 1; i <= n; i++) {int x = sc.nextInt(), y = sc.nextInt();a[i] = new Node(x, y);}Arrays.sort(a, 1, n + 1);for (int i = 0; i <= 10; i++) Last[i] = 0;for (int i = 1; i <= n; i++) {for (int y = 0; y <= 10; y++) if (Last[y] > 0) addEdge(i, Last[y]);Last[a[i].y] = i;}kruskal();}
}

Python代码

from typing import List, Tuple
def mul(b):  return b * b
class Node:def __init__(self, x: int, y: int):self.x = xself.y = ydef __lt__(self, other: "Node") -> bool:return self.x < other.x
class Edge:def __init__(self, u: int, v: int, w: int):self.u = uself.v = vself.w = wdef __lt__(self, other: "Edge") -> bool:return self.w < other.w
N = 100005
a: List[Node] = [Node(0, 0) for i in range(N)]
e: List[Edge] = [Edge(0, 0, 0) for i in range(N * 11)]
s: List[int] = [i for i in range(N)]
Last: List[int] = [0] * 15
n = m = 0
def addEdge(u: int, v: int) -> None:global mm += 1e[m].u = ue[m].v = ve[m].w = mul(a[u].x - a[v].x) + mul(a[u].y - a[v].y)def findSet(x: int) -> int:global sif x != s[x]:  s[x] = findSet(s[x])return s[x]def kruskal() -> None:global n, m, s, efor i in range(1, n + 1):  s[i] = ie[1:] = sorted(e[1:m + 1])ans = 0for i in range(1, m + 1):u = findSet(e[i].u)v = findSet(e[i].v)if u == v:  continues[u] = vans += e[i].wprint(ans)
if __name__ == "__main__":n = int(input())for i in range(1, n + 1):x, y = map(int, input().split())a[i] = Node(x, y)a[1:] = sorted(a[1:n + 1])Last = [0] * 15for i in range(1, n + 1):for y in range(11):if Last[y] > 0:  addEdge(i, Last[y])Last[a[i].y] = ikruskal()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/15046.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

09-特殊的向量

0 向量 就是分量全为 0 的向量 &#xff08;0 0 … 0&#xff09;单位向量 就是 L2 范数/模/长度为 1 的向量 如果一个向量大部分的位置为0&#xff0c; 少部分为非0的数&#xff0c; 那这样的向量我们就称之为稀疏向量&#xff0c; 反之为稠密向量&#xff0c; 它们是数学里面…

5、VMWARE安装、MobaXterm SSH连接 、Ubuntu xrdp安装使用

以下是在VMware中安装Ubuntu 22.04的详细步骤&#xff1a; 下载Ubuntu 22.04镜像文件&#xff1a; 前往Ubuntu官方网站或其他可信来源&#xff0c;下载Ubuntu 22.04的镜像文件&#xff08;.iso格式&#xff09;。 创建虚拟机&#xff1a; 打开VMware Workstation软件&#xf…

Servlet文件的下载

第一种方法直接在前端使用超链接&#xff0c;也就是a标签 浏览器不能识别会直接下载&#xff08;像压缩文件不能直接下载&#xff09;&#xff0c;浏览器能识别&#xff0c;想要下载加一个download属性。download可以不写任何信息。 首先在web下建一个文件&#xff0c;放需要…

在Windows 10和11中恢复已删除的照片

可以在Windows 10或11上恢复已删除的照片吗&#xff1f; 随着技术的发展&#xff0c;越来越多的用户习惯在电子设备上存储照片。如果这些照片被删除&#xff0c;可能会给用户带来重大损失。当照片丢失时&#xff0c;您可能会想是否可以恢复已删除的照片&#xff1f; …

Kafka原理剖析

一、简介 Kafka是一个分布式的、分区的、多副本的消息发布-订阅系统&#xff0c;它提供了类似于JMS的特性&#xff0c;但在设计上完全不同&#xff0c;它具有消息持久化、高吞吐、分布式、多客户端支持、实时等特性&#xff0c;适用于离线和在线的消息消费&#xff0c;如常规的…

内网隧道代理技术(十五)之 Earthworm的使用(二级代理)

Earthworm的使用(二级代理) 本文紧接着上一篇文章继续讲解Earthworm工具的使用 (二级代理)正向连接 二级正向代理发生在如下的情况: 1、Web服务器在公网,黑客可以直接访问 2、B机器在内网,黑客不能直接访问 3、Web服务器可以访问内网机器B 4、内网机器B可以访问公司…

ARM将常数加载到寄存器方法之LDR伪指令

一、是什么&#xff1f; LDR Rd,const伪指令可在单个指令中构造任何32位数字常数,使用伪指令可以生成超过MOV和MVN指令 允许范围的常数. 实现原理: (1)如果可以用MOV或MVN指令构造该常数,则汇编程序会生成适当的指令 (2)如果不能用MOV或MVN指令构造该常数,则汇编程序会执行下列…

【UE5】快速认识入门

目录 &#x1f31f;1. 快速安装&#x1f31f;2. 简单快捷键操作&#x1f31f;3. 切换默认的打开场景&#x1f31f;4. 虚幻引擎术语 &#x1f31f;1. 快速安装 进入Unreal Engine 5官网进行下载即可&#xff1a;UE5 &#x1f4dd;官方帮助文档 打开后在启动器里创建5.2.1引擎…

Vue2 第七节 Vue监测数据更新原理

&#xff08;1&#xff09;Vue会监视data中所有层次的数据 &#xff08;2&#xff09;如何监测对象中的数据 通过setter实现监视&#xff0c;且要在new Vue时传入要监测的数据对象中后追加的属性&#xff0c;Vue默认不做响应式处理如果要给后添加的属性做响应式&#xff0c;使…

【雕爷学编程】MicroPython动手做(18)——掌控板之声光传感器2

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

小研究 - 基于解析树的 Java Web 灰盒模糊测试(二)

由于 Java Web 应用业务场景复杂, 且对输入数据的结构有效性要求较高, 现有的测试方法和工具在测试Java Web 时存在测试用例的有效率较低的问题. 为了解决上述问题, 本文提出了基于解析树的 Java Web 应用灰盒模糊测试方法. 首先为 Java Web 应用程序的输入数据包进行语法建模创…

【C++】模板

前言 在我们平时的代码中经常会有不同类型的变量去执行效果差不多的函数。比如&#xff1a;swap(交换)&#xff0c;sort(排序)。这些函数里其实会有大部分重复的段落&#xff0c;在这种情况下我们会使用重载函数&#xff0c;但是函数重载会有如下的问题&#xff1a; 1. 重载的函…

测试开源C#人脸识别模块ViewFaceCore(4:口罩检测、性别预测、年龄预测)

ViewFaceCore模块中的MaskDetector类支持识别人脸是否戴了口罩或有遮挡&#xff0c;主要调用PlotMask函数执行口罩检测操作&#xff0c;其函数原型如下所示&#xff1a; PlotMaskResult PlotMask<T>(T image, FaceInfo info)public class PlotMaskResult{//// 摘要:// …

RabbitMQ 教程 | 第2章 RabbitMQ 入门

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 DevO…

VMware Linux 可视化增加磁盘

1、VMware 增加磁盘 2、disks挂载磁盘 此处我挂载的是20G磁盘&#xff0c;截图只是用5G的做过程演示例子。 3、验证挂载磁盘

动手学深度学习v2笔记 —— 线性回归 + 基础优化算法

二 动手学深度学习v2 —— 线性回归 基础优化算法 目录: 线性回归基础优化方法 1. 线性回归 总结 线性回归是对n维输入的加权&#xff0c;外加偏差使用平方损失来衡量预测值和真实值的差异线性回归有显示解线性回归可以看作是单层神经网络 2. 基础优化方法 梯度下降 小批量…

Spring的创建及使用

文章目录 什么是SpringSpring项目的创建存储Bean对象读取Bean对象getBean()方法 更简单的读取和存储对象的方式路径配置使用类注解存储Bean对象关于五大类注解使用方法注解Bean存储对象Bean重命名 Bean对象的读取 使用Resource注入对象Resource VS Autowired同一类型多个bean对…

echart折线图,调节折线点和y轴的间距(亲测可用)

options代码&#xff1a; options {tooltip: {trigger: axis, //坐标轴触发&#xff0c;主要在柱状图&#xff0c;折线图等会使用类目轴的图表中使用。},xAxis: {type: category,//类目轴&#xff0c;适用于离散的类目数据&#xff0c;为该类型时必须通过 data 设置类目数据。…

iOS开发-启动页广告实现

iOS开发-启动页广告实现 启动页广告实现是一个非常常见的广告展示模式。 就是在启动时候显示广告&#xff0c;之后点击跳转到广告页面或者其他APP。 一、实现启动页广告 启动页广告控件实现&#xff0c;将View放置在keyWindow上&#xff0c;显示广告图片&#xff0c;点击广告…

Pytorch(二)

一、分类任务 构建分类网络模型 必须继承nn.Module且在其构造函数中需调用nn.Module的构造函数无需写反向传播函数&#xff0c;nn.Module能够利用autograd自动实现反向传播Module中的可学习参数可以通过named_parameters()返回迭代器 from torch import nn import torch.nn.f…