题目描述

某国有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. 全栈项目|小书架|微信小程序-点赞功能实现

    微信小程序端的点赞功能其实没什么好介绍的,无非就是调用接口改变点赞状态和点赞数量.需要注意的是取消点赞时的处理,我这里为了减少服务器接口的调用,直接本地存一个变量,修改这里的变量值即可. 由于源码都相 ...

  2. pyhon opencv mojave 摄像头报错

    https://blog.csdn.net/renzibei/article/details/82998933 参考了上面博主的例子,才明白. Mac macOS 10.14 Mojave Xcode ...

  3. IPv4如何转换为IPv6?

    ipv6已经逐渐在应用,现在已经有很多的运营商支持ipv6,前天我们也发布了如何让电脑使用ipv6地址?有很多朋友在问?ipv6有什么作用,它的表示方式是什么,今天我们来一起来详细了解下ipv6相关计 ...

  4. spring boot 规范json返回值

    spring boot 规范json返回值 spring boot 接口返回配置 @ResponseBody ,则返回自定义的对象,解析成json. 但是,部分字段能友好的展示出来.如 Date,Lo ...

  5. 编程风格统一配置EditorConfig

    EditorConfig 以纯原生无需任何插件支持 EditorConfig 代码风格配置的编辑器: Visual Studio 2017 开始添加了对 EditorConfig 的原生支持.Visu ...

  6. rsyslog传输指定目录下的全部日志数据

    准备: 两台Linux电脑 server(A):10.1.75.177 client(B):10.1.75.229 目的: 将B上的/usr/local/record目录下的所有日志数据传输到A的/v ...

  7. 大数据之kafka-02.搞定kafka专业术语

    02.搞定kafka专业术语 在kafka的世界中有很多概念和术语是需要我们提前理解并且熟练掌握的,下面来盘点一下. 之前我们提到过,kafka属于分布式的消息引擎系统,主要功能是提供一套完善的消息发 ...

  8. VMware 设置虚拟机Centos 上网的两种方式

    能在VMware上面安装虚拟机,不可能说是不让链接外网,只是在自己电脑上玩玩就可以了.因为学习需要,经常在自己笔记本上面搭建虚拟机,我经常使用的两种上网方式 一 NET方式上网 设置VMware Ne ...

  9. Flask入门很轻松(三)—— 模板

    Jinja2模板引擎 转载请在文章开头附上原文链接地址:https://www.cnblogs.com/Sunzz/p/10959471.html Flask内置的模板语言,它的设计思想来源于 Dja ...

  10. 17,Flask-admin后台管理系统总结

    导入包 from flask_admin import Admin,BaseView,expose,AdminIndexView from flask_admin.contrib.sqla impor ...