新的开始(朴素版prim算法)
2021/11/20 1:09:47
本文主要是介绍新的开始(朴素版prim算法),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
题目:新的开始
题目链接:https://ac.nowcoder.com/acm/problem/50362
题意:有n个矿井,有两种方法可以保证矿井的电力供应:
- 在该矿井上建立发电站,费用为v。
- 将该矿井与已有电力供应的矿井间建立电网,费用为p。
求保证所有矿井都有电力供应的最小花费。
输入描述:
第一行输入矿井个数n(1 <= n <= 300)。
接下来n行,第i个数vi表示在第i个矿井上建立发电站的费用。
接下来一个n * n的矩阵p,表示每两个矿井间建立电网的费用。
样例输入:
4
5
4
4
3
0 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0
样例输出:
9
样例解释:在4号矿井建立发电站,在1,4之间,1,2之间,1,3之间建立电网,费用为3 + 2 + 2 + 2 = 9。
题目分析:最小生成树,可以使用prim算法求解。
解题步骤:
- 建立一个虚点0,在虚点0和所有矿井之间连接一条vi的边,这样虚点0到矿井i的距离就可以替代在矿井i上建立发电站的费用。
- 以虚点0为起点,做prim算法即可得到答案。
AC代码:
#include<iostream>
using namespace std;
const int N = 310, inf = 1e9;
int g[N][N], dis[N], b[N], n;
int prim(){
for(int i = 1;i <= n;i++) dis[i] = inf;
dis[0] = 0;
int res = 0;
for(int i = 0;i <= n;i++){
int t = -1;
for(int j = 0;j <= n;j++){
if(b[j] == 0 && (t == -1 || dis[j] < dis[t])) t = j;
}
res += dis[t];
b[t] = 1;
for(int j = 0;j <= n;j++) dis[j] = min(dis[j], g[t][j]);
}
return res;
}
void solve(){
scanf("%d", &n);
for(int i = 1;i <= n;i++) scanf("%d", &g[0][i]);
for(int i = 1;i <= n;i++){
for(int j = 1;j <= n;j++){
scanf("%d", &g[i][j]);
}
}
printf("%d\n", prim());
}
int main(void){
solve();
return 0;
}
时间复杂度:O(n ^ 2)。
空间复杂度:O(n ^ 2)。
这篇关于新的开始(朴素版prim算法)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南