题目描述
输入输出样例
4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0
28
AC Code
#include <iostream>
using namespace std;
const int maxn = 105;
typedef long long ll;
const ll INFINITY = 100005;
int g[maxn][maxn] = {0},lowcost[maxn] = {0};
int n;
ll ans = 0;
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>g[i][j];
}
}
for(int i=1;i<=n;i++){
lowcost[i] = g[1][i];
}
for(int i=1;i<n;i++){
int j = 1,k = 0,MIN = INFINITY;
while(j <= n){
if(lowcost[j]&&lowcost[j]<MIN){
MIN = lowcost[j];
k = j;
}
j++;
}
ans += MIN;
lowcost[k] = 0;
for(j=1;j<=n;j++){
if(lowcost[j]&&g[k][j]<lowcost[j]){
lowcost[j] = g[k][j];
}
}
}
cout<<ans;
return 0;
}
解释
Prim算法没什么可说的,本题直接给出了邻接矩阵,而没有给出“点点权值”这样的数据,无法使用Kruscal,因此只能用Prim。没什么可说的,这是一道Prim模板题,有一点需要注意:
for(int i=1;i<n;i++){
int j = 1,k = 0,MIN = INFINITY;
while(j <= n){
if(lowcost[j]&&lowcost[j]<MIN){
MIN = lowcost[j];
k = j;
}
j++;
}
ans += MIN;
lowcost[k] = 0;
for(j=1;j<=n;j++){
if(lowcost[j]&&g[k][j]<lowcost[j]){
lowcost[j] = g[k][j];
}
}
此处是Prim的核心,学过数据结构的同学都知道,Prim在运行前,需要先将一个图中任意顶点加入到生成树当中,再由这一点向外扩张,此处加入的是 0 这一个点,而上述代码中的最外层循环,实际上只是一个计数循环,因为还有 n-1 个点需要加入,使用while会更好,因为使用for可能会带来误解。