感觉还是理解题目比较难一些。。
算法还是Prim,没有特别 的变化。之前都按自己的理解写的Prim,这次看了算法导论中的伪代码,原来Prim还有更快速的实现方法。这个方法把与树的距离用一个域储存了一起,这样就不用每次都查找与树相邻的边了。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
#include<algorithm>
#include<climits>
#define FOR(i, N) for(int i = 1; i <= (N); i++)
using namespace std;
int cost[2001][2001];
char code[2001][10];
int getDist(int i, int j){
int dist = 0;
FOR(k, 7){
if(code[i][k - 1] != code[j][k - 1])
dist++;
}
return dist;
}
void read(int N){
FOR(i, N){
scanf("%s", code[i]);
FOR(j, i){
cost[i][j] = cost[j][i] = getDist(i, j);
}
}
}
int Prim(int N){
int distTotal = 0;
int key[2001];
bool inTree[2001];
FOR(i, N)
key[i] = INT_MAX;
memset(inTree, false, sizeof(inTree));
key[1] = 0;
FOR(i, N){
int keyMin = INT_MAX;
int index;
FOR(i, N)
if(!inTree[i] && keyMin > key[i]){
keyMin = key[i];
index = i;
}
FOR(i, N){
if(key[i] > cost[index][i])
key[i] = cost[index][i];
}
distTotal += keyMin;
inTree[index] = true;
}
return distTotal;
}
int main(){
int N;
while(cin >> N && N != 0){
read(N);
printf("The highest possible quality is 1/%d.\n", Prim(N));
}
}