题目:http://poj.org/problem?id=1789
AC代码(C++):
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <queue>
#include <math.h>
#include <string>
#include <string.h>
#include <bitset>
#define INF 0xfffffff
#define MAXN 2005
using namespace std;
int n;
int map[MAXN][MAXN];
int dis[MAXN];
bool vis[MAXN];
int getDist(string a, string b){
int ans = 0;
string::iterator ita = a.begin();
string::iterator itb = b.begin();
for(int i = 0; i < 7; i++){
if(*ita!=*itb)ans++;
ita++;
itb++;
}
return ans;
}
int Prim(){
int ans = 0;
for(int i=0;i<n;i++)dis[i]=map[0][i];
memset(vis,false,sizeof(vis));
vis[0]=1;
for(int i=1;i<n;i++){
int next,tmp = INF;
for(int j=0;j<n;j++){
if(!vis[j]&&tmp>dis[j]){
tmp=dis[j];
next=j;
}
}
ans += tmp;
vis[next]=1;
for(int j=0;j<n;j++){
if(!vis[j]&&dis[j]>map[next][j])
dis[j]=map[next][j];
}
}
return ans;
}
int main(){
while(cin>>n){
if(n==0)break;
string type[MAXN];
for(int i = 0; i < n; i++)cin>>type[i];
for(int i = 0; i < n; i++){
for(int j = 0; j <= i; j++){
map[i][j] = getDist(type[i],type[j]);
map[j][i] = map[i][j];
}
}
cout<<"The highest possible quality is 1/"<<Prim()<<"."<<endl;
}
}
总结: 水题, 虽然题目有点难懂. 其实大概就是有n种卡车型号(都是长度为7的字符串), 两型号间的distance就是两字符串有多少位不同, 一种型号只能由另一种型号派生出来, 要你计算出要怎么派生才能使得总distance最小. 那么把每个型号看做是节点, 节点两两间都有一边, 距离就是distance, 要你求这个图的最小生成树的总长度. 所以构造好这个图之后直接用prim就能解决了.