题目描述

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)条路分别连接了哪两个农场,他希望你计算一下,为了使得所有农场连通,他所需建造道路的最小总长是多少。

输入格式

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

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

输出格式

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


很容易想到这是最小生成树的题,只不过多了一个限制:有m条已连接的边。

但是也很容易求解,而且有两种容易想到的方法:

1.把m条已连接的边看成:m条长度为0的边。修改边权后排序,敲个最小生成树模板即可。修改边权可以用map来做,由于一共有N * (N-1)/2条边,所以复杂度为:

\[O(Mlog\frac{N(N-1)}{2})\approx{O(MlogN^2)}
\]

最小生成树可以用Prim+Heap或者Kruskal做,所以时间复杂度总共为:

\[O((N+M)log\frac{N(N-1)}{2})\approx{O((N+M)logN^2)}
\]

或者:

\[O((M+\frac{N(N-1)}{2})log\frac{N(N-1)}{2})\approx{O((M+N^2)logN^2)}
\]

虽然看上去不一样,其实两种都是差不多的。

2.做Kruskal时,我们会从小到大枚举每条边,如果边上的两端点不在一个集合中就选中这条边。受启发于此,我们可以把每条已连接的边的两个端点都用并查集合并到一个集合中。由于Kruskal中的并查集操作复杂度非常小(因为在不停地路径压缩),所以这里把它忽略掉。那么总共的时间复杂度就是:

\[O(M+\frac{N(N-1)}{2}log\frac{N(N-1)}{2})\approx{O(M+N^2logN^2)}
\]

还是挺不错的

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define maxn 1001
#define maxm 1000001
using namespace std; struct edge{
int u,v; double w;
edge(){}
edge(const int &_u,const int &_v,const double &_w){ u=_u,v=_v,w=_w; }
bool operator<(const edge &e)const{ return e.w-w>1e-9; }
}e[maxm]; int fa[maxn];
int x[maxn],y[maxn];
int n,m,k;
double ans; inline int read(){
register int x(0),f(1); register char c(getchar());
while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
} int get(int x){
if(fa[x]==x) return x;
return fa[x]=get(fa[x]);
} int main(){
n=read(),m=read();
for(register int i=1;i<=n;i++) x[i]=read(),y[i]=read();
for(register int i=1;i<n;i++){
for(register int j=i+1;j<=n;j++)
e[++k]=edge(i,j,(double)sqrt((double)(x[i]-x[j])*(x[i]-x[j])+(double)(y[i]-y[j])*(y[i]-y[j])));
} sort(e+1,e+1+k);
for(register int i=1;i<=n;i++) fa[i]=i;
for(register int i=1;i<=m;i++){
int u=read(),v=read();
fa[get(u)]=get(v);
}
for(register int i=1;i<=k;i++){
int u=get(e[i].u),v=get(e[i].v);
if(u==v) continue;
fa[u]=v,ans+=e[i].w;
}
printf("%.2lf\n",ans);
return 0;
}

[Usaco2007 Dec]Building Roads 修建道路的更多相关文章

  1. BZOJ 1626: [Usaco2007 Dec]Building Roads 修建道路( MST )

    计算距离时平方爆了int结果就WA了一次...... ------------------------------------------------------------------------- ...

  2. bzoj 1626: [Usaco2007 Dec]Building Roads 修建道路 -- 最小生成树

    1626: [Usaco2007 Dec]Building Roads 修建道路 Time Limit: 5 Sec  Memory Limit: 64 MB Description Farmer J ...

  3. [Usaco2007 Dec]Building Roads 修建道路[最小生成树]

    Description Farmer John最近得到了一些新的农场,他想新修一些道路使得他的所有农场可以经过原有的或是新修的道路互达(也就是说,从任一个农场都可以经过一些首尾相连道路到达剩下的所有农 ...

  4. bzoj1626[Usaco2007 Dec]Building Roads 修建道路

    Description Farmer John最近得到了一些新的农场,他想新修一些道路使得他的所有农场可以经过原有的或是新修的道路互达(也就是说,从任一个农场都可以经过一些首尾相连道路到达剩下的所有农 ...

  5. 【BZOJ】1626: [Usaco2007 Dec]Building Roads 修建道路(kruskal)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1626 依旧是水题..太水了.. #include <cstdio> #include & ...

  6. BZOJ——1626: [Usaco2007 Dec]Building Roads 修建道路

    http://www.lydsy.com/JudgeOnline/problem.php?id=1626 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1 ...

  7. BZOJ 1626 [Usaco2007 Dec]Building Roads 修建道路:kruskal(最小生成树)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1626 题意: 有n个农场,坐标为(x[i],y[i]). 有m条原先就修好的路,连接农场( ...

  8. bzoj 1626: [Usaco2007 Dec]Building Roads 修建道路【最小生成树】

    先把已有的边并查集了,然后MST即可 记得开double #include<iostream> #include<cstdio> #include<algorithm&g ...

  9. bzoj1626 / P2872 [USACO07DEC]道路建设Building Roads

    P2872 [USACO07DEC]道路建设Building Roads kruskal求最小生成树. #include<iostream> #include<cstdio> ...

随机推荐

  1. bp VNext 入门——让ABP跑起来

    因好多群友@我说,ABP他们简单的了解了下,按照官方的教程一路下来跑不起来(倒在了入门的门口),才有了此文. 此文结合官方文档,一步一步带领大家让ABP跑起来(跨过门口). 建议大家一步一步实际动手操 ...

  2. 最详细10招Spark数据倾斜调优

    最详细10招Spark数据倾斜调优 数据量大并不可怕,可怕的是数据倾斜 . 数据倾斜发生的现象 绝大多数 task 执行得都非常快,但个别 task 执行极慢. 数据倾斜发生的原理 在进行 shuff ...

  3. .Net 常用ORM框架对比:EF Core、FreeSql、SqlSuger

    前言: 最近由于工作需要,需要选用一种ORM框架,也因此对EF Core.FreeSql.SqlSuger作简单对比.个人认为各有有优势,存在即合理,不然早就被淘汰了是吧,所以如何选择因人而议.因项目 ...

  4. Helm 带你飞

    文章目录 目录 文章目录 在没使用 Helm之前,向 K8S部署应用,我们要依次部署 deployment. svc 等,步骤较繁琐.况且随着很多项目微服务化,复杂的应用在容器中部署以及管理显得较为复 ...

  5. RabbitMQ 详解 五种队列-SpiritMark

    上次带大家看了一下RabbitMQ的基本概念,今天我们来详解一下 RabbitMQ的五种队列,也算是一个笔记,如果对您有帮助,可以关注一下,便于下次光顾! 文章目录 1.简单队列 2.work 模式 ...

  6. 一个小技巧助您减少if语句的状态判断

    作者:依乐祝 首发地址:https://www.cnblogs.com/yilezhu/p/14174990.html 在进行项目的开发的过程中, if 语句是少不了的,但我们始终要有一颗消灭 if  ...

  7. 深入理解MySQL系列之锁

    按锁思想分类 悲观锁 优点:适合在写多读少的并发环境中使用,虽然无法维持非常高的性能,但是在乐观锁无法提更好的性能前提下,可以做到数据的安全性 缺点:加锁会增加系统开销,虽然能保证数据的安全,但数据处 ...

  8. 编程方式实现MySQL批量导入sql文件

    有时候需要在本地导入一些stage环境的数据到本地mysql,面对1000+的sql文件(包含表结构和数据,放在同一个文件夹下),使用navicat一个一个导入sql文件显然有点太慢了,于是考虑使用s ...

  9. Json串的字段如果和类中字段不一致,如何映射、转换?

    Json串是我们现在经常会遇到的一种描述对象的字符串格式.在用Java语言开发的功能中,也经常需要做Json串与Java对象之间的转换. fastjson就是经常用来做Json串与Java对象之间的转 ...

  10. java保持同一时间同一账号只能在一处登录

    //登录页面 login.jsp <%@ page language="java" contentType="text/html; charset=UTF-8&qu ...