最小生成树prim算法直接应用。最小生成树不唯一,所采用的算法设计思想是贪心。计算两个顶点集合U, V 中顶点的最短距离(最小代价)是关键,每次计算的复杂度是O(n * n)。但是可以采用空间换时间的方案降低复杂度到O(n)。在示例代码中采取的就是这种方案。
#include<iostream>
#include<fstream>
using namespace std;
static const int MAXNODES = 27;
static const int MAXINT = ((unsigned)-1) >> 1;
static int weigh[MAXNODES][MAXNODES];
static int key[MAXNODES];
static int isin[MAXNODES];
static int cost;
static int n;
//#define DEBUG
/* 252K 0MS */
void prim()
{
int i, j;
key[1] = 0; isin[1] = 0;
for (i = 2; i <= n; i++) //初始化
{ key[i] = MAXINT; isin[i] = 0; }
for (cost = 0, i = 1; i <= n; i++)
{
int min = MAXINT;
int mini = -1;
for(j = 1; j <= n; j++)
{
if (!isin[j] && key[j] < min)
{ min = key[j]; mini = j; }
}
isin[mini] = 1; cost += min; // 找到最小cost
for (j = 1; j <= n; j++) // 更新cost信息
{
if (!isin[j] && weigh[mini][j] < key[j])
key[j] = weigh[mini][j];
}
}
}
int main()
{
int i, j;
while (cin >> n && n)
{
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
weigh[i][j] = MAXINT;
for (i = 1; i< n; i++)
{
char u, v;
int k, w;
cin >> u >> k;
while (k-- > 0)
{
cin >> v >> w;
weigh[u - 'A' + 1][v - 'A' + 1] = w;
weigh[v - 'A' + 1][u - 'A' + 1] = w;
}
}
prim();
cout << cost << "\n";
}
return 0;
}
prim算法直接应用,该题在输入上面比较特别,需要费点事。
在测试用例中不是直接以邻接矩阵进行输入的。所以在开始读取用例数据前先需要对邻接矩阵做一个初始化。