题目链接:http://poj.org/problem?id=1789
将题目转化为最小生成树,求最小权值Q;一个字符串编号为一个顶点,两个字符串之间不相同字符的个数即为边的权值;
#include<iostream>
using namespace std;
const int inf=1<<26;
int n;
int graph[2001][2001];
bool visit[2001];//用来表示顶点v是否已加入最小生成树中。
int low_w[2001];//用来保存非生成树中各顶点与生成树中顶点最短边的权值
char str[2001][8];
int prim()
{
int pos_flag;
int prim_w=0;
int min_w;
int i,j;
/*Initial*/
for(i=1;i<=n;i++)
{
low_w[i]=graph[1][i];
visit[i]=false;
}
visit[1]=true;
/*Prime Algorithm*/
for(i=1;i<n;i++)
{
min_w=inf;
for(j=1;j<=n;j++)
{
if(!visit[j] && min_w>low_w[j])//寻找当前未被标记的最小权值点
{
min_w=low_w[j];
pos_flag=j;
}
}
prim_w += min_w;
visit[pos_flag]=true;//把点pos_falg加入到最小生成树中
for(j=1;j<=n;j++)//更新由顶点pos_flag到其他未加入生成树的顶点 边的权值
{
if(!visit[j] && low_w[j]>graph[pos_flag][j])
low_w[j]=graph[pos_flag][j];
}
}
return prim_w;
}
int main(int i,int j)
{
for(;;)
{
cin>>n;
if(!n) break;
/*Input*/
for(i=1;i<=n;i++)
cin>>str[i];
/*建图*/
memset(graph,0,sizeof(graph));
for(i=1;i<=n-1;i++)
{
for(j=i+1;j<=n;j++)
{
for(int k=0;k<7;k++)
{
if(str[i][k]!=str[j][k])//计算不同字符个数,双向建图
{
graph[i][j]++;
graph[j][i]++;
}
}
}
}
cout<<"The highest possible quality is 1/"<<prim()<<'.'<<endl;
}
return 0;
}