题目描述

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. centos 7 yum 安装 python3

    sudo yum install epel-release sudo yum install python34参考:http://stackoverflow.com/questions/8087184 ...

  2. sqoop用法之mysql与hive数据导入导出

    目录 一. Sqoop介绍 二. Mysql 数据导入到 Hive 三. Hive数据导入到Mysql 四. mysql数据增量导入hive 1. 基于递增列Append导入 1). 创建hive表 ...

  3. NET 5 Cron表达式

    cron表达式通过特定的规则指定时间,用于定时任务 1. 整体结构 cron表达式是一个字符串,分为6或7个域,每两个域之间用空格分隔,其语法格式为: "秒域 分域 时域 日域 月域 周域 ...

  4. python序列(十)字典

    字典是无序可变序列. 定义字典是,每个元素的键和值用冒号分隔,元素之间用逗号分隔,所有的元素放在一对大括号"{ }"中. 字典中的键可以为任意不可变数据,比如.整数.实数.复数.字 ...

  5. Nginx timeout配置

    缘由:客户测试反馈Request failed with status code 504,后续排查应该是nginx未配置超时设置 Step 1.打开nginx.conf查看 缺少keepalive_t ...

  6. 国产的开源数据库——GitHub 热点速览 Vol.52

    作者:HelloGitHub-小鱼干 本以为本周的 GitHub 和十二月一样平平无奇就那么度过了,结果 BackgroundMattingV2 重新刷新了本人的认知,还能这种骚操作在线实时抠视频去背 ...

  7. 解决在Filter中读取Request中的流后, 然后再Control中读取不到的做法

    摘要: 大家知道, StringMVC中@RequestBody是读取的流的方式, 如果在之前有读取过流后, 发现就没有了. 我们来看一下核心代码: filter中主要做的事情, 就是来校验请求是否合 ...

  8. 【探索之路】机器人篇(2)-ROS系统并创建工作空间和项目

    在ROS官网,已经给出了详细的教程.下面我就般一下砖,把相应的操作写到这里.官方网址:http://wiki.ros.org/cn/ 安装ROS系统 indigo在ubuntu上的安装教程.官网:ht ...

  9. Keil4 uVision软件生成hex文件

    keil4下载地址:http://www.pc6.com/softview/SoftView_236836.html 按图操作即可,注意文件夹选择. 1.选择工程,选择第一个new uvision p ...

  10. 解决npm ERR!

    一:[Unexpected end of JSON input while parsing near]报错 最近的vue项目中在执行 npm install 时会报错误: npm ERR! Unexp ...