题目地址
AC代码
#include <cstring>
#include <cstdio>
using namespace std;
int markVertex[2001];
char temp[2001][8];
int list[2001][2001];
int dist[2001];
int main() {
int n;
while(scanf("%d",&n),n!=0) {
memset(list,0, sizeof(list));
memset(markVertex,0,sizeof(markVertex));
memset(temp,0,sizeof(temp));
for (int i = 0; i < n; ++i) {
scanf("%s",temp[i]);
}
for (int i = 0; i < n; ++i) {
for (int j = i+1; j < n; ++j) {
for (int k = 0; k < 7; ++k) {
if (temp[i][k] != temp[j][k]){
list[i][j]++;
list[j][i]++;
}
}
}
}
int boo = 0, counter = 0,pos = 0;
markVertex[0] = 1;
for (int l = 0; l < n; ++l) {
dist[l]=list[0][l];
}
while (1) {
if(boo==n-1)break;
boo++;
int mini = 5555;
for (int i = 0; i < n; ++i) {
if(markVertex[i])continue;
if(dist[i]<mini){
pos = i;
mini = dist[i];
}
}
counter+=mini;
markVertex[pos]= 1;
for (int j = 0; j < n; ++j) {
if(j==pos)continue;
if(list[pos][j]<dist[j])dist[j]=list[pos][j];
}
}
printf("The highest possible quality is 1/%d.\n",counter);
}
return 0;
}
题解和题目思路
题目的意思是让你从给出的所有序列号中找出一个派生路线,使得按照这个路线进行派生所需要改动的总字符数最少,所以就是最小生成树的查找,Prim就可以了,如果想查找出来派生路线,只需要增加两个数组,一个数组用来记录当前dist数组各个元素对应的集合内点的编号,另一个来记录边的路线(二维)