1 条题解
-
0
自动搬运
来自洛谷,原作者为

MY(一名蒟蒻)
你数据结构都用错了,怎么改都是没用的。搬运于
2025-08-24 21:23:06,当前版本为作者最后更新于2020-09-12 15:21:22,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
今天CSP刚报好名,刚好 这题。听说比赛前写题解可以+rp,于是就有了这篇题解。
0.审题
题面前面一大堆有的没的,蛋是
当所有城市被组合成一个“城市联盟”时,修建工程也就完成了。一语道破目的:最小生成树。
其实你不分析题面的话也不知道。最小生成树是什么呢,实际上就是给您一个图,要求把图变成一个由n-1(n为点数)条边组成的图,使得总边权最小。
该不会真的有人不知道最小生成树是什么就来做这题吧,不会吧不会吧(大雾1.思路
第一反应Kruskal,于是写完一提交直接爆炸。
:存边数组爆炸
:爆炸
于是Prim大法好啊!!!
Prim算法流程:
- 开始将起点(本题随意)标记为蓝点;
- 找一条连接蓝点集合中一点和白点集合中一点最短的边;
- 将该边连接的白点加入蓝点;
- 将该新加入的蓝点所有连接的白点最短边更新;
- 返回第二步,直到n个点都被选入最小生成树为止。
注:蓝点为已加入最小生成树的点,白点反之。
2.代码实现
相信大家可以发现,这个算法流程跟
Dijkstra差不多,于是代码实现也很相似。因为算法流程已经给出,代码注释将不再赘述。
code:
#include <cstdio> #include <iostream> #include <cmath> #include <cstring> #include <string> #include <algorithm> using namespace std; int n; typedef double dou; dou x[5010],y[5010],dis[5010],book[5010],ans; dou get_e(dou x1,dou y1,dou x2,dou y2) {//求两点间距离函数 return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } void init()//初始化 { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%lf%lf",&x[i],&y[i]); dis[i]=1e12*1.0;//double类很大,炸不了 } return ; } void Prim() { dis[1]=0.0; book[1]=true; int curr; double minn; for(int i=1;i<=n;i++) { curr=1; minn=1e9*1.0; for(int j=1;j<=n;j++)//找最短边 if(!book[j] && dis[j] < minn) minn=dis[j],curr=j; book[curr]=true; ans+=dis[curr]; for(int j=1;j<=n;j++)//现用现算 dis[j]=min(dis[j],get_e(x[curr],y[curr],x[j],y[j])); } printf("%.2lf",ans); return ; } int main() { // freopen("work.in","r",stdin);freopen("work.out","w",stdout); init(); Prim(); // fclose(stdin);fclose(stdout); return 0; }Thank you for your reading!
拒绝白嫖,从我做起。点个赞再走嘛。
- 1
信息
- ID
- 265
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者