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.

Farmer John最近得到了一些新的农场,他想新修一些道路使得他的所有农场可以经过原有的或是新修的道路互达(也就是说,从任一个农场都可以经过一些首尾相连道路到达剩下的所有农场)。有些农场之间原本就有道路相连。 所有N(1 <= N <= 1,000)个农场(用1..N顺次编号)在地图上都表示为坐标为(X_i, Y_i)的点(0 <= X_i <= 1,000,000;0 <= Y_i <= 1,000,000),两个农场间道路的长度自然就是代表它们的点之间的距离。现在Farmer John也告诉了你农场间原有的M(1 <= M <= 1,000)条路分别连接了哪两个农场,他希望你计算一下,为了使得所有农场连通,他所需建造道路的最小总长是多少。

输入格式

* 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.

  • 第1行: 2个用空格隔开的整数:N 和 M

  • 第2..N+1行: 第i+1行为2个用空格隔开的整数:X_i、Y_i

  • 第N+2..N+M+2行: 每行用2个以空格隔开的整数i、j描述了一条已有的道路, 这条道路连接了农场i和农场j

输出格式

* 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.

输出使所有农场连通所需建设道路的最小总长,保留2位小数,不必做 任何额外的取整操作。为了避免精度误差,计算农场间距离及答案时 请使用64位实型变量

输入输出样例

输入 #1

4 1
1 1
3 1
2 3
4 3
1 4
输出 #1

4.00

说明/提示

题目简述:给出n个点的坐标,其中一些点已经连通,现在要把所有点连通,求修路的最小长度.

(来自洛谷)

因为要求把所有的点联通的最小长度,直接求最小生成树。

至于一部分已经修好的路径,既然不用再修(肯定在树内且无需计权值),对于每条路直接添加一条权值为0的边即可。

我用了一个vector存储路径,每次穷举两个点求欧几里得距离插入边,最后加入那些0权值边后Kruskal算法直接解决。

#include <bits/stdc++.h>
using namespace std;
int m, n;
double rslt;
double posx[], posy[];
struct edge{
int from, to;
double val;
};
vector <edge> g;
int edge_cnt;
bool cmp(const edge &x, const edge &y){
if(x.val == y.val){
if(x.from == y.from) return x.to < y.to;
return x.from < y.from;
}
return x.val < y.val;
}
void add_edge(int f, int t, double v){
g.push_back((edge){f, t, v});
g.push_back((edge){t, f, v});
edge_cnt += ;
} int father[];
int find(int x){
if(father[x] != x) father[x] = find(father[x]);
return father[x];
} void add_place(){
for(int i=; i<n; i++){
for(int j=i+; j<=n; j++){
double len = (double)sqrt((double)(posx[i] - posx[j]) * (posx[i] - posx[j]) + (double)(posy[i] - posy[j]) * (posy[i] - posy[j]));
add_edge(i, j, len);
}
}
return;
} void kruskal(){
for(int i=; i<n; i++){
father[i] = i;
}
sort(g.begin(), g.end(), cmp);
int cnt;
for(int i=; i<edge_cnt; i++){
int f1 = find(g[i].from), f2 = find(g[i].to);
if(f1 != f2){
rslt += g[i].val;
father[f1] = f2;
if(++cnt == n-) return;
}
} } int main(){
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
cin >> n >> m;
for(int i=; i<=n; i++){
cin >> posx[i] >> posy[i];
}
add_place();
for(int i=; i<m; i++){
int f, t;
cin >> f >> t;
add_edge(f, t, );
}
kruskal();
printf("%.2f", rslt);
return ;
}

最新文章

  1. 压缩png质量不改变像素
  2. .NET平台下对C3D文件的读写
  3. 【iOS开发】在 App 中加入 AdMob 广告 - 入门介绍与编程技巧
  4. 【BZOJ-1670】Building the Moat护城河的挖掘 Graham扫描法 + 凸包
  5. Embed dll Files Within an exe (C# WinForms)—Winform 集成零散dll进exe的方法
  6. hdu4738 Caocao&#39;s Bridges
  7. 推荐!Sublime Text 最佳插件列表
  8. 线性模型(2):Linear Regression
  9. requestCode 和 resultCode .
  10. php 二维数组以树形输出(转)
  11. 学用 ASP.Net 之 System.Math 类
  12. mysql sql学习(一)mysql连接
  13. mysql存储过程中in、out、inout参数使用实际案例
  14. Linux下ftp的安装配置
  15. Educational Codeforces Round 2_B. Queries about less or equal elements
  16. 【天坑】ASP.net WebAPI跨域调用问题
  17. osgearth介绍
  18. ArcMap图层属性表中添加图片
  19. 窗体背景和png
  20. 【C#数据结构系列】线性表

热门文章

  1. python 关于excel弹窗——请注意,您的文档的部分内容可能包含了文档检查器无法删除的个人信息解决方法
  2. spring5 源码深度解析----- 事务增强器(100%理解事务)
  3. 为什么一个Http Header中的空格会被骇客利用 - HTTP request smuggling
  4. CSDN VIP如何添加引流自定义栏目
  5. 洛谷NOIp热身赛 T2123 数列游戏
  6. Json模块(dumps、loads、dump、load)函数篇
  7. 算法学习之剑指offer(八)
  8. badboy录制脚本
  9. postman常用断言
  10. 后渗透神器Cobalt Strike的安装