题目大意:输入几个字符串,每个字符串可以转化为别的字符串,两个字符串同位置不同的数目称为转化值,要求找到转化值最小的方案。
题目可以看成顶点全部连通的完全图,找出最小生成树,权值即为转化值。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <algorithm>
#include <cmath>
using namespace std;
const int inf=10;
int n;
char s[2001][8];
int dist[2001][2001]={0};
int dif(int i,int j)
{
int k,count=0;
for(k=0;k<7;k++)
{
if(s[i][k]!=s[j][k])
{
count++;//找出不同的数目
}
}
return count;
}
int prim()
{
int s=1;//最短路
int m=1;//顶点个数
bool u[2001];//是否属于最小生成树
int sum=0;//权值
int min;//新源点到其他点的最短路
int point;
int dis[2001];//各个源点到其他点的最短路
memset(dis,inf,sizeof(dis));
memset(u,false,sizeof(u));
u[s]=true;
while(1)
{
if(m==n)//最小生成树顶点个数
{
break;
}
min=inf;
for(int j=2;j<=n;j++)
{
if(!u[j]&&dis[j]>dist[s][j])
{
dis[j]=dist[s][j];
}
if(!u[j]&&min>dis[j])
{
min=dis[j];
point=j;
}
}
s=point;
u[s]=true;
sum+=min;
m++;
}
return sum;
}
int main()
{
int i,j;
while(cin>>n)
{
if(n==0)
{
break;
}
for(i=1;i<=n;i++)
{
cin>>s[i];
}
for(i=1;i<=n-1;i++)
{
for(j=i+1;j<=n;j++)
{
dist[i][j]=dist[j][i]=dif(i,j);
}
}
cout<<"The highest possible quality is 1/"<<prim()<<'.'<<endl;
}
return 0;
}