/*
题意:题目很长很坑爹很难理解,就是每种卡车都由特定的7个字母组成的代码表示,而且每种卡车都是由
其它种类的卡车衍生而来(除了初始的那辆祖先卡车);从卡车a衍生到卡车b,它们的distance为两种卡车代
码的相应位置字母不同的数目,现在给出n种卡车,保证代码都不同,两两之间既可能a衍生到b,也可能b衍
生到a;求出其中一种情况使得从其中某辆车衍生出所有其它车,并且使所有distance值之和最小。
题解:最小生成树,prim算法;
每种车都只能由一种车衍生而来,只有初始的那辆为祖先,很明显构成了一颗树,只有根结点没有前驱,其
余结点都只有一个父结点,给出的所有卡车两两相互连接构成一个无向图,边值为distance,显然是从无向
图中找出最小生成树。
*/
#include <cstdio>
#include <cstring>
using namespace std;
int map[2005][2005];
char s[2005][10];
int prim(int n)
{
int from,min,sum=0;
bool vis[2005];
int low[2005];
memset(vis,false,sizeof(vis));
vis[0] = true;
from = 0;
for(int i=0; i<n; i++)
low[i] = map[from][i];
for(int i=1; i<n; i++)
{
min = 20;
for(int j=0; j<n; j++)
{
if (!vis[j] && low[j]<min)
{
min = low[j];
from = j;
}
}
sum += min;
vis[from] = true;
for(int j=0; j<n; j++)
{
int t = map[from][j];
if (!vis[j] && low[j]>t)
low[j] = t;
}
}
return sum;
}
int main(void)
{
int n;
while (~scanf("%d",&n) && n)
{
memset(map,0,sizeof(map));
scanf("%*c");
for(int i=0; i<n; i++)
{
for(int j=0; j<7; j++)
scanf("%c",&s[i][j]);
scanf("%*c");
}
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
if (i != j)
{
for(int k=0; k<7; k++)
if (s[i][k] != s[j][k])
map[i][j]++;
}
}
}
printf("The highest possible quality is 1/%d.\n",prim(n));
}
return 0;
}