题意:有很多长度为7的字符串编号,一个编号可以由其他字符串衍生出来,代价是这两个编号之间相应的distance,现在要找出一个“衍生”方案,使得总代价最小,也就是distance之和最小。
distance=两个字符串之间不同字符的个数。
题解:就是求最小生成树的总权重,即每次以最小的代价衍生一个编号。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <stack>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
using namespace std;
#define LL long long
#define M 2002
#define INF 1<<30
#define CLS(x,v) memset(x,v,sizeof(x))
#define FOR(i,a,n) for(int i=(a);i<=(n);++i)
/**0x7f*/
int graph[M][M];
int n;
int prim(int s)
{
bool vis[M];
int dist[M];
CLS(dist,0x7f);
dist[s]=0;
CLS(vis,0);
int k,ret=0;
for(int i=0; i<n; i++)
{
k=-1;
for(int j=1; j<=n; j++)
if(!vis[j]&&(k==-1||dist[j]<dist[k]))
k=j;
vis[k]=1;
ret+=dist[k];
for(int j=1; j<=n; j++)
if(!vis[j]&&graph[k][j]&&graph[k][j]<dist[j])
dist[j]=graph[k][j];
}
return ret;
}
char s[M][8];
int compareDist(char *s,char *t)
{
int ret=0;
for(int i=0;s[i];i++)
if(s[i]!=t[i])
ret++;
return ret;
}
int main()
{
while(~scanf("%d",&n)&&n)
{
FOR(i,1,n)scanf("%s",s[i]);
CLS(graph,0);
FOR(i,1,n)FOR(j,(i+1),n)
{
graph[i][j]=graph[j][i]=compareDist(s[i],s[j]);
}
printf("The highest possible quality is 1/%d.\n",prim(1));
}
return 0;
}