最短网络(朴素版prim算法)
题目:最短网络
题目链接:https://ac.nowcoder.com/acm/problem/22936
题意:有n个农场,每两个农场的距离不超过100000,要在农场间铺设光纤,求能够连接所有农场的最小光纤和。
输入描述:
第一行给出农场的个数n(3 <= n <= 100)。
接下来给出一个n * n的矩阵表示每两个农场间的距离。
输出描述:
输出能够连接所有农场的最小光纤和。
样例输入:
4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0
样例输出:
28
样例解释:
选择光纤连接农场1和2,2和3,3和4,距离分别为4,8,16,总和为28。
题目分析:最小生成树裸题,可以以农场1作为起点,使用prim算法求解。
解题步骤:
1. 初始化dis[1]为0,dis[2]到dis[n]为inf,表示各个农场i到已选定的农场的集合的最小距离。
2. 进行n次迭代,每次选出未选定,且离已选定的农场的集合的最小距离最小的农场,并利用选出的农场去尝试更新其他农场到已选定的农场的集合的最小距离。
AC代码:
#include<iostream>
using namespace std;
const int N = 110, inf = 1e9;
int dis[N], g[N][N], b[N], n;
int prim(){
for(int i = 1;i <= n;i++) dis[i] = inf;
dis[1] = 0;
int res = 0;
for(int i = 1;i <= n;i++){
int t = -1;
for(int j = 1;j <= n;j++){
if(b[j] == 0 && (t == -1 || dis[j] < dis[t])) t = j;
}
res += dis[t];
b[t] = 1;
for(int j = 1;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++){
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)。

浙公网安备 33010602011771号