题目大意: 有n个字符创代表n个车型, 每个车型都是另外一个车型派生出来的, 最初的那个假设存在。派生的代价就是两个字符串的不同字符的个数。 求派生出所有车辆的最小的代价。
题目分析: 每一辆都得派生出来, 代价最小, 最小生成树裸题。 把每辆车之间的代价求出来做边权重, 每辆车做顶点建图。 每辆车相互之间都有边, 稠密图, 因此用Prim算法。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int INF = 1 << 31 -1;
int cost[2005][2005];
char s[2005][8];
int n;
int mincost[2005];
bool used[2005];
int Prim(int s)
{
int ans = 0;
for(int i=0; i<n; ++i)
{
mincost[i] = INF;
used[i] = false;
}
mincost[s] = 0;
while(true)
{
int v = -1;
for(int i=0; i<n; ++i)
if(!used[i] && (v == -1 || mincost[i] < mincost[v])) v = i;
if(v == -1) break;
used[v] = true;
ans += mincost[v];
for(int i=0; i<n; ++i)
{
mincost[i] = min(mincost[i], cost[v][i]);
}
}
return ans;
}
int main()
{
while(scanf("%d", &n) && n)
{
memset(cost, 0, sizeof(cost));
for(int i=0; i<n; ++i)
scanf("%s", s[i]);
for(int i=0; i<n; ++i)
for(int j=0; j<=i; ++j)
{
for(int k=0; k<7; ++k)
if(s[i][k] != s[j][k]) ++cost[i][j];
cost[j][i] = cost[i][j];
}
printf("The highest possible quality is 1/%d.\n", Prim(0));
}
return 0;
}