POj 1789
- 重点在建图,每个字符串是一个顶点,权值是字符串每个位置字符不同的个数,
- 每两个字符串之间的边权值相同,方向相反,所以不需要完全2层循环建图.
for (int i=1; i<=n; i++)
for (int j=i; j<=n; j++) {
a[i][j] = a[j][i] = countnum(ch[i],ch[j]);
}
#include <iostream>
#include <string.h>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 2010;
int a[maxn][maxn];
char ch[maxn][8];
bool vis[maxn];
int dist[maxn];
int n;
void prim() {
memset(vis, 0 ,sizeof vis);
vis[1] = 1;
for (int i=1; i<=n; i++) dist[i] = a[1][i];
long sum = 0;
for (int i=1; i<n; i++) {
long minn = INF;
int point = INF;
for (int i=1; i<=n; i++) {
if (!vis[i] && dist[i]<minn ) {
point = i;
minn = dist[i];
}
}
vis[point] = true;
sum += dist[point];
for (int i=1; i<=n; i++) {
if ( !vis[i] && a[point][i]<dist[i] )
dist[i] = a[point][i];
}
}
printf("The highest possible quality is 1/%d.\n",sum);
}
int countnum(char* a,char* b) {
int cnt = 0;
for (int i=0; i<7; i++)
if (a[i] != b[i])
cnt++;
return cnt;
}
int main() {
while (scanf("%d",&n) && n) {
memset(a,0x3f,sizeof a);
for (int i=1; i<=n; i++) scanf("%s",ch[i]);
for (int i=1; i<=n; i++)
for (int j=i; j<=n; j++) {
a[i][j] = a[j][i] = countnum(ch[i],ch[j]);
}
prim();
}
return 0;
}