Truck History
Time Limit: 2000MS |
|
Memory Limit: 65536K |
Total Submissions: 19527 |
|
Accepted: 7534 |
Description
Advanced Cargo Movement, Ltd. uses trucks of different types. Some trucks are used for vegetable delivery, other for furniture, or for bricks. The company has its own code describing each type of a truck. The code is simply a string of exactly seven lowercase letters (each letter on each position has a very special meaning but that is unimportant for this task). At the beginning of company's history, just a single truck type was used but later other types were derived from it, then from the new types another types were derived, and so on.
Today, ACM is rich enough to pay historians to study its history. One thing historians tried to find out is so called derivation plan -- i.e. how the truck types were derived. They defined the distance of truck types as the number of positions with different letters in truck type codes. They also assumed that each truck type was derived from exactly one other truck type (except for the first truck type which was not derived from any other type). The quality of a derivation plan was then defined as
1/Σ(to,td)d(to,td)
where the sum goes over all pairs of types in the derivation plan such that t
o
is the original type and t
d
the type derived from it and d(t
o,t
d) is the distance of the types.
Since historians failed, you are to write a program to help them. Given the codes of truck types, your program should find the highest possible quality of a derivation plan.
Input
The input consists of several test cases. Each test case begins with a line containing the number of truck types, N, 2 <= N <= 2 000. Each of the following N lines of input contains one truck type code (a string of seven lowercase letters). You may assume that the codes uniquely describe the trucks, i.e., no two of these N lines are the same. The input is terminated with zero at the place of number of truck types.
Output
For each test case, your program should output the text "The highest possible quality is 1/Q.", where 1/Q is the quality of the best derivation plan.
Sample Input
4
aaaaaaa
baaaaaa
abaaaaa
aabaaaa
0
Sample Output
The highest possible quality is 1/3.
为了不那么明显的说出此题的解题方法,就说一下题意,不抽象的说出算法了:说在一个汽车公司中,每种车的种类能用一个字符串(定长为7)唯一地表示,对于两种不同种类的车是可以互相衍生的,就是由A种类的车可以衍生出B种类车,需要付出的代价是:表示A,B两种车的字符串中,对应位置上的不相同的个数。
像这样:
A:aaaaaaa
B:abaaaca
两种车的字符串中,第二个和第六个这2个位置上的字符不一样,所以由A衍生出B的代价为:2 。同样这种衍生是双向的,即同时也可以由B衍生出A,代价一样为2。
现在该公司要做一个计划,要设计出N种车,每种车的字符串表示已给出,那么按什么样的顺序进行挨个衍生效果最好。
衡量效果的方法是:衍生出N种车用的总代价的倒数。
思路是:最小生成树
从一种种类A衍生出种类B,代价为c,相当于A顶点到B顶点的权值为c,又因为A衍生出B和B衍生出A是一样的,所以图是无向图。然后直接用最小生成树做就好了。
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
char d[2003][9];
struct pp
{
int a,b;
int v;
}s[4000002];
int cmp(const pp &x,const pp &y)
{
return x.v<y.v;
}
int count(char s1[],char s2[])
{
int cnt=0,i;
for(i=0;i<7;i++)
if(s1[i]!=s2[i])
cnt++;
return cnt;
}
int f[2002];
void init(int n)
{
int i;
for(i=0;i<=n;i++)
f[i]=i;
}
int find(int x)
{
return f[x]==x?x:f[x]=find(f[x]);
}
int Union(int x,int y)
{
if((x=find(x))==(y=find(y)))
return 0;
f[y]=x;
return 1;
}
int main()
{
int i,j,k,n,cnt,aa,bb,res;
while(scanf("%d",&n),n)
{
for(i=1;i<=n;i++)
scanf("%s",d[i]);
init(n);
k=0;
for(i=1;i<n;i++)
{
for(j=i+1;j<=n;j++)
{
s[k].a=i;s[k].b=j;
s[k++].v=count(d[i],d[j]);
}
}
sort(s,s+k,cmp);
res=0;cnt=0;
for(i=0;i<k;i++)
{
if(Union(s[i].a,s[i].b))
{
res+=s[i].v;
cnt++;
}
if(cnt==n-1)
break;
}
if(cnt==n-1)
printf("The highest possible quality is 1/%d.\n",res);
}
return 0;
}