题意
给出n个编号为A~A+n的节点,和某些节点之间的距离,求最小生成树的总权值
思路
裸的Prim算法求最小生成树
算法细节:
最小生成树-Prim算法和Kruskal算法
AC代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define mst(a) memset(a, 0, sizeof(a))
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 30;
ll all;
int n;
int mc[maxn], d[maxn][maxn], vis[maxn];
void init(){
all = 0;
mst(mc);
mst(d);
mst(vis);
for( int i = 1; i <= maxn; i++ ){
for( int j = 1; j <= maxn; j++ ){
d[i][j] = i == j ? 0 : INF;
}
}
}
ll prim(){
for( int i = 1; i <= n; i++ ){
mc[i] = INF;
vis[i] = 0;
}
mc[1] = 0;
int all = 0;
for(;;){
int v = -1;
for( int i = 1; i <= n; i++ ){
if(!vis[i] && (v == -1 || mc[i] < mc[v] ) )
v = i;
}
if( v == -1 ) break;
vis[v] = 1;
all += mc[v];
for( int i = 1; i <= n; i++ )
mc[i] = min(mc[i], d[v][i]);
}
return all;
}
int main()
{
int T, nn, cost;
char f, t;
while( scanf("%d",&T) == 1 && T ){
n = T;
init();
getchar();
for( int i = 1; i < T; i++ ){
scanf("%c",&f);getchar();
scanf("%d",&nn);getchar();
//printf("%c %d
", f, n);
while(nn--){
scanf("%c",&t);getchar();
scanf("%d",&cost);getchar();
//printf("%c %d
", t, cost);
int xx = f-'A'+1, yy = t-'A'+1;
if( cost < d[xx][yy] ){
d[xx][yy] = cost;
d[yy][xx] = cost;
}
}
}
printf("%lld
",prim());
}
return 0;
}