题目描述

某国有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. Drools入门

    文章转载自:http://cwqcwq.iteye.com/blog/397869 一.背景知识:  1.什么是规则引擎  Java规则引擎起源于基于规则的专家系统,而基于规则的专家系统又是专家系统的 ...

  2. windows 10 如何设定计划任务自动执行 python 脚本?

    我用 python 写了一些脚本,有一些是爬虫脚本,比如爬取知乎特定话题的热门问题,有一些是定期的统计分析脚本,输出统计结果到文档中.之前我都是手动执行这些脚本,现在我希望如何这些脚本能自动定时执行. ...

  3. [golang]svg图片默认按照左上角旋转,改为按中心旋转,重新计算中心偏移量

    1 前言 svg图片默认按照左上角旋转,改为按中心旋转,重新计算中心偏移量 2 代码 type Point struct { X float64 Y float64 } func GetOffsetX ...

  4. 换个语言学一下 Golang (8)——指针

    定义 所谓指针其实你可以把它想像成一个箭头,这个箭头指向(存储)一个变量的地址. 因为这个箭头本身也需要变量来存储,所以也叫做指针变量. Go的指针不支持那些乱七八糟的指针移位.它就表示一个变量的地址 ...

  5. 【开发笔记】- 在Windows环境下后台启动redis

    1. 进入 DOS窗口 2. 在进入Redis的安装目录 3. 输入:redis-server --service-install redis.windows.conf --loglevel verb ...

  6. JavaScript原型链以及Object,Function之间的关系

    JavaScript里任何东西都是对象,任何一个对象内部都有另一个对象叫__proto__,即原型,它可以包含任何东西让对象继承.当然__proto__本身也是一个对象,它自己也有自己的__proto ...

  7. Falsk框架 Session 与 Flask-Session

    目录 Cookie 与 Session 简单了解 Falsk 中 Session 的保管机制 相关的配置 使用 Flask-Session 三方组件 基础练习题 Cookie 与 Session 简单 ...

  8. [LeetCode] 198. 打家劫舍 ☆(动态规划)

    描述 你是一个专业的小偷,计划偷窃沿街的房屋.每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警. 给定一个 ...

  9. [JavaScript] js中全局标识正则表达式的lastIndex属性

    在JavaScript中使用正则表达式时,遇到一个坑:第一次匹配是true,第二次匹配是false. 因为在带全局标识"g"的正则表达式对象中,才有“lastIndex” 属性,该 ...

  10. 通过cmd命令将jar放到maven仓库

    如:将jar包直接拷贝到mave仓库的文件夹是不能直接使用的,需要通过cmd命令将jar生产maven可用的 mvn install:install-file -Dfile=iTextAsian-1. ...