F - Building Roads S

Description

Farmer John had just acquired several new farms! He wants to connect the farms with roads so that he can travel from any farm to any other farm via a sequence of roads; roads already connect some of the farms.

Each of the N (1 ≤ N ≤ 1,000) farms (conveniently numbered 1...N) is represented by a position (Xi, Yi) on the plane (0 ≤ Xi ≤ 1,000,000; 0 ≤ Yi ≤ 1,000,000). Given the preexisting M roads (1 ≤ M ≤ 1,000) as pairs of connected farms, help Farmer John determine the smallest length of additional roads he must build to connect all his farms.

给定 nn 个点的坐标,第 ii 个点的坐标为 (xi,yi)(xi​,yi​),这 nn 个点编号为 11 到 nn。给定 mm 条边,第 ii 条边连接第 uiui​ 个点和第 vivi​ 个点。现在要求你添加一些边,并且能使得任意一点都可以连通其他所有点。求添加的边的总长度的最小值。

Input

* Line 1: Two space-separated integers: N and M

* Lines 2...N+1: Two space-separated integers: Xi and Yi

* Lines N+2...N+M+2: Two space-separated integers: i and j, indicating that there is already a road connecting the farm i and farm j.

第一行两个整数 n,mn,m 代表点数与边数。

接下来 nn 行每行两个整数 xi,yixi​,yi​ 代表第 ii 个点的坐标。

接下来 mm 行每行两个整数 ui,viui​,vi​ 代表第 ii 条边连接第 uiui​ 个点和第 vivi​ 个点。

Output

* Line 1: Smallest length of additional roads required to connect all farms, printed without rounding to two decimal places. Be sure to calculate distances as 64-bit floating point numbers.

一行一个实数代表添加的边的最小长度,要求保留两位小数,为了避免误差, 请用 6464 位实型变量进行计算。

Sample 1

Inputcopy Outputcopy
4 1 1 1 3 1 2 3 4 3 1 4 4.00

Hint

数据规模与约定

对于 100%100% 的整数,1≤n,m≤10001≤n,m≤1000,1≤xi,yi≤1061≤xi​,yi​≤106,1≤ui,vi≤n1≤ui​,vi​≤n。

说明

Translated by 一只书虫仔。

最小生成树,但要注意要加上m中已经为树的边数

复制代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
int n, m, ll = 0,v,u,ss=0;
double min = 0.00;
int b[1001];
struct pppp {
	int x, y;
}bb[1001];
struct s {
	int x, y;
	double k;
};
struct s a[1000001], d[1000001];
//归并排序将其从小到打排序
void digui(int i, int j) {
	if (i >= j) {
		return;
	}
	int mid = i + (j - i) / 2;
	digui(i, mid);
	digui(mid + 1, j);
	int r = i, l = mid + 1, h = i;
	while (r <= mid && l <= j) {
		if (a[r].k < a[l].k) {
			d[h].k = a[r].k;
			d[h].x = a[r].x;
			d[h].y = a[r].y;
			h++;
			r++;
		}
		else {
			d[h].k = a[l].k;
			d[h].x = a[l].x;
			d[h].y = a[l].y;
			h++;
			l++;
		}
	}
	while (r <= mid) {
		d[h].k = a[r].k;
		d[h].x = a[r].x;
		d[h].y = a[r].y;
		h++;
		r++;
	}
	while (l <= j) {
		d[h].k = a[l].k;
		d[h].x = a[l].x;
		d[h].y = a[l].y;
		h++;
		l++;
	}
	h = i;
	while (h <= j) {
		a[h].k = d[h].k;
		a[h].x = d[h].x;
		a[h].y = d[h].y;
		h++;
	}
}
//并查集
int cha(int i) {
	if (b[i] != i) {
		return b[i]= cha(b[i]);
	}
	else {
		return b[i];
	}
}
int main() {
	scanf("%d %d", &n, &m);
	for (int i = 1;i <= n;i++) {
		b[i] = i;
	}
	for (int i = 1;i <= n;i++) {
		scanf("%d %d", &bb[i].x, &bb[i].y);
	}
	for (int i = 1;i <= m;i++) {
		scanf("%d %d", &u, &v);
		if (b[cha(u)] == b[cha(v)])//可能有已经是同一个合集相连
			ss++;
		b[cha(u)] = b[cha(v)];
	}
	int e = 0;
	for (int i = 1;i <= n;i++) {
		for (int j = i + 1;j <= n;j++) {
			a[e].x = i;
			a[e].y = j;
			a[e].k = (double)(sqrt((double)pow(bb[i].x - bb[j].x,2)  + (double)pow(bb[i].y - bb[j].y,2)));
			e++;
		}
	}
	digui(0, e - 1);
	int i = 0;
	while (ll <n-m-1+ss&&i<e) {
		if (cha(a[i].x) != cha(a[i].y)) {
			min += a[i].k;
			b[cha(a[i].y)] = b[cha(a[i].x)];
			ll++;
		}
		i++;
	}
	printf("%.2lf\n", min);
	return 0;
}
相关推荐
未来之窗软件服务几秒前
幽冥大陆(三十九)php二维数组去重——东方仙盟筑基期
android·开发语言·算法·php·仙盟创梦ide·东方仙盟·东方仙盟sdk
DFT计算杂谈4 分钟前
Abinit-10.4.7安装教程
linux·数据库·python·算法·matlab
sali-tec13 分钟前
C# 基于halcon的视觉工作流-章65 点云匹配-基于形状
开发语言·人工智能·算法·计算机视觉·c#
AI科技星24 分钟前
自然本源——空间元、氢尺、探针与场方程
数据结构·人工智能·算法·机器学习·计算机视觉
小O的算法实验室33 分钟前
2025年CMAME SCI2区,基于优先级驱动搜索、具备动态候选解管理策略的粒子群算法,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
吃着火锅x唱着歌37 分钟前
LeetCode 2874.有序三元组中的最大值II
数据结构·算法·leetcode
xxxxxmy1 小时前
相向双指针—三数之和
python·算法·相向双指针
Blossom.1181 小时前
基于知识图谱+LLM的工业设备故障诊断:从SQL日志到可解释推理的实战闭环
人工智能·python·sql·深度学习·算法·transformer·知识图谱
conkl1 小时前
梅森旋转算法深度解析:构建更健壮的前端请求体系
前端·算法·状态模式
老黄编程1 小时前
点云NARF关键点原理、算法描述及参数详细描述
算法·点云·narf特征点