Prim算法:
Prim算法实现的是找出一个有权重连通图中的最小生成树,即:具有最小权重且连接到所有结点的树。(强调的是树,树是没有回路的)。
Prim算法是这样来做的:
首先以一个结点作为最小生成树的初始结点,然后以迭代的方式找出与最小生成树中各结点权重最小边,并加入到最小生成树中。加入之后如果产生回路则跳过这条边,选择下一个结点。当所有结点都加入到最小生成树中之后,就找出了连通图中的最小生成树了。
#include <iostream>
using namespace std;
const int MAX_NUM = 2002;
const int CODE_LEN = 7;
const int INF = 0x3F3F3F3F;
char code[MAX_NUM][CODE_LEN+1];
int graph[MAX_NUM][MAX_NUM];
int dist[MAX_NUM];
bool vis[MAX_NUM];
int n;
//计算两个编码间的距离
int diff(const char* str1, const char* str2)
{
int i, d = 0;
for (i = 0; i < CODE_LEN; ++i){
if (str1[i] != str2[i]){
++d;
}
}
return d;
}
int prim()
{
int i, j, cur = 1, qt = 0;
memset(vis, 0, sizeof(vis));
vis[cur] = true;
dist[1] = 0; //选1作为起始点
for (i = 2; i <= n; ++i){
dist[i] = INF;
}
for (i = 1; i < n; ++i){
int min = INF;
int p;
for (j = 1; j <= n; ++j){
if (!vis[j]){
//更新集合与集合外点的距离
if (dist[j] > graph[cur][j]){
dist[j] = graph[cur][j];
}
//选去距离最小的纳入集合
if (dist[j] < min){
min = dist[j];
p = j;
}
}
}
cur = p;
vis[cur] = true;
qt += dist[cur];
}
return qt;
}
int main()
{
int i, j;
while (scanf("%d", &n) && n != 0){
for (i = 1; i <= n; ++i){
scanf("%s", code[i]);
}
for (i = 1; i <= n; ++i){
for (j = i+1; j <= n; ++j){
graph[i][j] = graph[j][i] = diff(code[i], code[j]);
}
}
printf("The highest possible quality is 1/%d.\n", prim());
}
return 0;
}