题目描述

某国有n个城市,它们互相之间没有公路相通,因此交通十分不便。为解决这一“行路难”的问题,政府决定修建公路。修建公路的任务由各城市共同完成。

修建工程分若干轮完成。在每一轮中,每个城市选择一个与它最近的城市,申请修建通往该城市的公路。政府负责审批这些申请以决定是否同意修建。

政府审批的规则如下:

(1)如果两个或以上城市申请修建同一条公路,则让它们共同修建;

(2)如果三个或以上的城市申请修建的公路成环。如下图,A申请修建公路AB,B申请修建公路BC,C申请修建公路CA。则政府将否决其中最短的一条公路的修建申请;

(3)其他情况的申请一律同意。

一轮修建结束后,可能会有若干城市可以通过公路直接或间接相连。这些可以互相:连通的城市即组成“城市联盟”。在下一轮修建中,每个“城市联盟”将被看作一个城市,发挥一个城市的作用。

当所有城市被组合成一个“城市联盟”时,修建工程也就完成了。

你的任务是根据城市的分布和前面讲到的规则,计算出将要修建的公路总长度。

输入格式

第一行一个整数n,表示城市的数量。(n≤5000)

以下n行,每行两个整数x和y,表示一个城市的坐标。(-1000000≤x,y≤1000000)

输出格式

一个实数,四舍五入保留两位小数,表示公路总长。(保证有惟一解)

输入输出样例

输入 #1复制

4
0 0
1 2
-1 2
0 4
输出 #1复制

6.47

说明/提示

修建的公路如图所示:

解析:

MST裸题(不接受挨打)

由于是稠密图,所以采用了Prim算法
(稀疏图最好用克鲁斯卡尔)
对任意两个点都求出距离
然后对其跑一遍最小生成树
但是注意n的范围是5000,而大小限制为125MB

题目本身不难,但是会一直MLE,所以需要优化

我这里有三个代码,不同的分数

第一个是裸的开 5000*5000 double数组的Prim算法可以跑出80分的好成绩(不开O2)。、

第二个是裸的克鲁斯卡尔算法,不开O2估计70分,开了O2稳定80分,运气好的话就是90分

第三个就是Prim,与第一个Prim不同的是会减少大量的冗余运算,具体体现就是把 5000 * 5000 的数组取消掉

只会在需要计算的时候才会计算,将大大减少时间和内存,,,所以就AC了。

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<iomanip>
#include<cstdlib>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#define LL long long
#define re register
#define INF 0x7fffffff
#define Max 5002
#define D double
inline int read()
{
int s=,f=-;char ch=getchar();
while(ch<''||ch>'') {if(ch=='-') f=-;ch=getchar();}
while(ch>=''&&ch<='') s=s*+ch-'',ch=getchar();
return s*f;
}
int n;D ans=0.0,g[Max][Max],dis[Max];
bool vis[Max]={};
struct edge {
D x,y;
}t[Max];
D Dis(D x1,D y1,D x2,D y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int main()
{
scanf("%d",&n);
for(re int i = ; i <= n ; ++ i) g[i][i]=,scanf("%lf%lf",&t[i].x,&t[i].y);
for(re int i = ; i <= n ; ++ i)
for(re int j = i+ ; j <= n ; ++ j)
g[i][j]=g[j][i]=Dis(t[i].x,t[i].y,t[j].x,t[j].y);
int pos;vis[]=;
for(re int i = ; i <= n ; ++ i) dis[i]=g[][i];
for(re int i = ; i < n ; ++ i) {
pos=;
for(re int j = ; j <= n ; ++ j) {
if(vis[j]==) continue;
if(!pos || dis[j] < dis[pos]) pos=j;
}
vis[pos]=;
ans+=dis[pos];
for(re int j = ; j <= n ; ++ j) {
if(vis[j]==) continue;
dis[j]=std::min(dis[j],g[pos][j]);
}
}
printf("%.2lf",ans);
return ;
}

80分裸的Prim

 // luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<iomanip>
#include<cstdlib>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#define LL long long
#define re register
#define Max 5000*5000/2
#define D double
inline int read()
{
int s=,f=-;char ch=getchar();
while(ch<''||ch>'') {if(ch=='-') f=-;ch=getchar();}
while(ch>=''&&ch<='') s=s*+ch-'',ch=getchar();
return s*f;
}
int n,pa[Max];D ans=;
struct edge {
D x,y;
}t[Max];
struct DIS {
D dis;
int from,to;
friend bool operator<(DIS a,DIS b) {
return a.dis<b.dis;
}
}e[Max];
int find(int x)
{
if(x!=pa[x]) pa[x]=find(pa[x]);
return pa[x];
}
void join(int x,int y)
{
x=find(x);y=find(y);
pa[y]=x;
}
D Dis(D x1,D y1,D x2,D y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int main()
{
scanf("%d",&n);int cnt=;
for(re int i = ; i <= n ; ++ i) pa[i]=i,scanf("%lf%lf",&t[i].x,&t[i].y);
for(re int i = ; i <= n ; ++ i)
for(re int j = i+ ; j <= n ; ++ j)
e[++cnt].dis=Dis(t[i].x,t[i].y,t[j].x,t[j].y),e[cnt].from=i,e[cnt].to=j;
int k=;
std::sort(e+,e++cnt);
for(re int i = ; i <= cnt ; ++ i) {
int x=e[i].from,y=e[i].to;D t=e[i].dis;
if(find(x)!=find(y)) join(x,y),ans+=t;
if(k==n-) break;
}
printf("%.2lf",ans);
return ;
}

开O2或许是90分或许是80分,看你是否脸黑

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<iomanip>
#include<cstdlib>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#define LL long long
#define re register
#define INF 0x7fffffff
#define Max 5002
#define D double
inline int read()
{
int s=,f=-;char ch=getchar();
while(ch<''||ch>'') {if(ch=='-') f=-;ch=getchar();}
while(ch>=''&&ch<='') s=s*+ch-'',ch=getchar();
return s*f;
}
int n;D ans=0.0,dis[Max];
bool vis[Max]={};
struct edge {D x,y;}t[Max];
D Dis(D x1,D y1,D x2,D y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
int main()
{
scanf("%d",&n);
for(re int i = ; i <= n ; ++ i) dis[i]=INF,scanf("%lf%lf",&t[i].x,&t[i].y);
int pos;dis[]=;
for(re int i = ; i <= n ; ++ i) {
D m=INF*1.0;
for(re int j = ; j <= n ; ++ j)
if(dis[j] < m && !vis[j]) m=dis[j],pos=j;
vis[pos]=;
ans+=m;
for(re int j = ; j <= n ; ++ j) {
if(vis[j]==) continue;
D d=Dis(t[pos].x,t[pos].y,t[j].x,t[j].y);
dis[j]=std::min(dis[j],d);
}
}
printf("%.2lf",ans);
return ;
}

AC 代码

洛谷P1265 公路修建题解的更多相关文章

  1. 洛谷P1265 公路修建(Prim)

    To 洛谷.1265 公路修建 题目描述 某国有n个城市,它们互相之间没有公路相通,因此交通十分不便.为解决这一“行路难”的问题,政府决定修建公路.修建公路的任务由各城市共同完成. 修建工程分若干轮完 ...

  2. 洛谷P1265 公路修建

    P1265 公路修建 177通过 600提交 题目提供者该用户不存在 标签图论 难度普及+/提高 提交该题 讨论 题解 记录 最新讨论 long long类型赋值-1为什么… p党80的进 为什么不过 ...

  3. 洛谷——P1265 公路修建

    P1265 公路修建 题目描述 某国有n个城市,它们互相之间没有公路相通,因此交通十分不便.为解决这一“行路难”的问题,政府决定修建公路.修建公路的任务由各城市共同完成. 修建工程分若干轮完成.在每一 ...

  4. 洛谷P1265 公路修建——prim

    给一手链接 https://www.luogu.com.cn/problem/P1265 这道题本质上就是最小生成树,题目描述就是prim的思想 TIP:注意稠密图和稀疏图的区别 #include&l ...

  5. 洛谷 [P1265] 公路修建

    本题的描述:城市联盟,最短距离.. 使人想到了prim求MST,再一看数据范围:完全图!,那么一定得用prim,因为只有5000个点,所以不加优化的prim就能过. #include <iost ...

  6. 洛谷P2832 行路难 分析+题解代码【玄学最短路】

    洛谷P2832 行路难 分析+题解代码[玄学最短路] 题目背景: 小X来到了山区,领略山林之乐.在他乐以忘忧之时,他突然发现,开学迫在眉睫 题目描述: 山区有n座山.山之间有m条羊肠小道,每条连接两座 ...

  7. 【洛谷P3960】列队题解

    [洛谷P3960]列队题解 题目链接 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m ...

  8. 洛谷P2242 公路维修问题

    To 洛谷.2242 公路维修问题 题目描述 由于长期没有得到维修,A国的高速公路上出现了N个坑.为了尽快填补好这N个坑,A国决定对M处地段采取交通管制.为了求解方便,假设A国的高速公路只有一条,而且 ...

  9. 洛谷P2312 解方程题解

    洛谷P2312 解方程题解 题目描述 已知多项式方程: \[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\] 求这个方程在 \([1,m]\) 内的整数解(\(n\) 和 \(m\) ...

随机推荐

  1. sqlserver安装教程

    1 安装步骤:http://jingyan.baidu.com/article/359911f573f71657fe030603.html 2 当提示装载第二张光盘时,在DAEMON Tools中把第 ...

  2. Java操作JSON数据(1)--JSON-lib操作JSON数据

    JSON-lib是一个java库,用于将bean.映射.集合.java数组和XML转换为JSON,或将JSON转为beans和DynaBeans.JSON-lib最后的版本是2.4,更新时间是2010 ...

  3. Python进阶----异常处理

    Python进阶----异常处理 一丶错误和异常   错误:       语法错误(这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正) #语法错误示范一 if #语法错误示范二 ...

  4. Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器

    Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器 一丶关键字:global,nonlocal global 声明全局变量: ​ 1. 可以在局部作用域声明一 ...

  5. mybatis 变更xml文件目录

    mybatis的xml默认读取的是resources目录,这个目录是可以变化的.我习惯于将mapper文件和xml放到一起或相邻目录下. 如图: 具体操作: 以mybatis-plus为例 boots ...

  6. 正则表达式修饰符 i、g、m、s、U、x、a、D、e 等。

    正则表达式中常用的模式修正符有i.g.m.s.U.x.a.D.e 等. 它们之间可以组合搭配使用. i 不区分(ignore)大小写: 例如: /abc/i 可以匹配 abc.aBC.Abc g 全局 ...

  7. HANA- SAP S4/HANA BP屏幕增强添加自定义字段(BDT方式)

    转载:https://www.cnblogs.com/hhelibeb/p/7412792.html 这里我们可以使用的技术是Business Data Toolset(以下简称BDT). 以下是网络 ...

  8. python错误日志记录工具,解决项目排错问题

    我们写项目的时候难免会遇到代码报错的问题,遇到这样的问题了如何快速的定位问题并解决问题呢? 我今天来整理了利用python只带的工具来解决这个问题,我能需要使用的库有: logging os 这些都是 ...

  9. PYTHON 文件读写、坐标寻址、查找替换

    读文件 打开文件(文件需要存在) #打开文件 f = open("data.txt","r") #设置文件对象 print(f)#文件句柄 f.close() ...

  10. 三星手机使用应用沙盒一键修改路由mac数据

    之前文章介绍了怎么在安卓手机上安装激活xposed框架,xposed框架的极强的功能大家都知道,能够不修改apk的前提下,修改系统底层的参数,打比方在某些应用情景,大家需要修改手机的某个系统参数,这情 ...