【ACWing】1140. 最短网络

news/2024/12/23 4:05:11/

题目地址:

https://www.acwing.com/problem/content/1142/

农夫约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。约翰的农场的编号是 1 1 1,其他农场的编号是 2 ∼ n 2∼n 2n。为了使花费最少,他希望用于连接所有的农场的光纤总长度尽可能短。你将得到一份各农场之间连接距离的列表,你必须找出能连接所有农场并使所用光纤最短的方案。

输入格式:
第一行包含一个整数 n n n,表示农场个数。接下来 n n n行,每行包含 n n n个整数,输入一个对角线上全是 0 0 0的对称矩阵。其中第 x + 1 x+1 x+1 y y y列的整数表示连接农场 x x x和农场 y y y所需要的光纤长度。

输出格式:
输出一个整数,表示所需的最小光纤长度。

数据范围:
3 ≤ n ≤ 100 3≤n≤100 3n100
每两个农场间的距离均是非负整数且不超过 100000 100000 100000

其实就是求最小生成树的总边长。可以用Prim算法。其思路大致是维护一个集合,同时维护所有不在这个集合里的点与该集合的最短距离,然后依次将距离最小的点加入集合,直到所有点都加进去为止。具体是这样的:
1、任选一个点 x x x,开一个距离数组 d d d,令 d [ x ] = 0 d[x]=0 d[x]=0,其余点的 d d d定为 + ∞ +\infty +
2、进行 n n n次循环, n n n是图的点数,每次循环的时候,找到不在 S S S中并且 d d d最小的点,将其加入集合 S S S(第一次循环的时候 S = ∅ S=\empty S=,由于选中了 x x x d [ x ] = 0 d[x]=0 d[x]=0,所以 x x x是第一个加入 S S S的点),并累加该边的长度;
3、循环结束后,就将 n n n个点都加入了 S S S,也就得到了一棵最小生成树。

关于算法的正确性,只需注意每次加的边一定能包含在某个最小生成树里即可。在已经加入的点的集合是 S S S时,如果某个从 x x x出发的到达 y y y的边在Prim算法里没有被选入,那么在生成的最小生成树里,由于 x x x y y y是连通的,所以这棵树加上 x → y x\to y xy这条边之后,就形成了一个环。这个环与 S S S相交的点除了 x x x之外,一定还有另一个点 z z z,从 z z z出发向外的一条边被这个最小生成树选中了,而将这条边换成 x → y x\to y xy这条边,能得到一个不会更差的最小生成树(这是由Prim算法选边的方式决定的)。这就证明了 x → y x\to y xy这条边是可以作为某个最小生成树的边的。再由数学归纳法即得Prim算法的正确性。

代码如下:

#include <iostream>
#include <cstring>
using namespace std;const int N = 110;
int n;
int a[N][N];
// dist[i]存i与集合的最短距离
int dist[N];
// st[i]存i这个点是否已经被选入集合
bool st[N];int prim() {memset(dist, 0x3f, sizeof dist);int res = 0;// 选中1号点,从这个点开始扩张为最小生成树dist[1] = 0;// 循环n次,每次加入一个点for (int i = 0; i < n; i++) {// 找到还没选中的点里与集合最小距离最小的点int t = -1;for (int j = 1; j <= n; j++)if (!st[j] && (t == -1 || dist[t] > dist[j])) t = j;// 累加边权,并将t并入集合res += dist[t];st[t] = true;// 以t的邻边来更新未加入集合的点的最小距离for (int j = 1; j <= n; j++)if (!st[j] && dist[j] > a[t][j])dist[j] = a[t][j];}return res;
}int main() {cin >> n;for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)cin >> a[i][j];cout << prim() << endl;return 0;
}

时间复杂度 O ( n 2 ) O(n^2) O(n2),空间 O ( n ) O(n) O(n)


http://www.ppmy.cn/news/438507.html

相关文章

s2011web登录密码_2011年最糟糕的密码

s2011web登录密码 Are you still using “password” to protect access to your vital administration systems? Of course not but, according to software security company SplashData, it’s still at #1 in the dumb password chart. Here’s the “top” 25 compiled f…

鼠标事件 获取鼠标坐标及点击事件

运行效果&#xff1a; 头文件 #ifndef MOUSEEVENT_H #define MOUSEEVENT_H #include #include #include #include class MouseEvent : public QMainWindow { Q_OBJECT public: MouseEvent(QWidget *parent 0); ~MouseEvent(); protected: void mousePressEvent(QMouse…

寝室空调遥控解码

以前寝室的空调遥控器由宿管阿姨掌管&#xff0c;私心想着&#xff0c;若能仿制个遥控器能有多好。 此处解码的空调型号为海尔KFR-35GW/06NCA12&#xff0c;所用红外协议为NEC协议。NEC协议是众多红外遥控协议的其中一种&#xff0c;除NEC外&#xff0c;还有RC5等其它协议。 …

微软商店下载的python 的 pip 不能修改 config 的解决方法

微软商店下载的python不能修改config的解决方法 找到图中文件的位置 C:\\Program Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.9_3.9.3312.0_x64__qbz5n2kfra8p0\\pip.ini 右键属性>安全 >高级 >更改 输入自己的用户名之后点确定 >确定 >确定 …

智能电视老是无服务器,只需简单几招,轻松解决智能电视无法连接WIFI问题

原标题&#xff1a;只需简单几招&#xff0c;轻松解决智能电视无法连接WIFI问题 看电视的时候&#xff0c;最痛苦的时候莫过于看到精彩情节的时候&#xff0c;网络不好&#xff0c;电视卡着不能播放&#xff0c;长时间无法恢复&#xff01;如果网络很久没有恢复的话&#xff0c…

SpringBoot第27讲:SpringBoot集成MySQL - MyBatis 多个数据源

SpringBoot第27讲&#xff1a;SpringBoot集成MySQL - MyBatis 多个数据源 本文是SpringBoot第27讲&#xff0c;在某些场景下&#xff0c;Springboot需要使用多个数据源&#xff0c;以及某些场景会需要多个数据源的动态切换。本文主要介绍上述场景及 SpringBootMyBatis实现多个数…

苏宁api接口

请求参数&#xff1a;num_iid0071261484/000000012252673695 参数说明&#xff1a;num_iid:店铺ID/商品ID API接口工具 { "item": { "num_iid": "0071261484/000000012252673695", "title": "array(格力…

3D模型检索

1、引言 在互联网、计算机辅助设计&#xff08;CAD&#xff09;、分子生物学&#xff08;3D蛋白质模型&#xff09;、计算机图形学、医药以及考古学等不同领域中&#xff0c;大型的三维&#xff08;3D&#xff09;数据库变得越来越普遍。近期在激光扫描技术的进展使我们可以方…