题意:求出从这若干序列中选出一个生成其他序列,所需变化花费最小的序列
链接:http://poj.org/problem?id=1789
思路:根据公式可知,要求的d的和就是生成最小树的权值,建图时注意将每一个序列作为一个节点,两个节点之间的权值为需要变化字母的个数
注意点:无
以下为AC代码:
Run ID | User | Problem | Result | Memory | Time | Language | Code Length | Submit Time |
14176748 | luminous11 | 1789 | Accepted | 16476K | 547MS | G++ | 1847B | 2015-05-09 09:28:34 |
/*
***********************************************
*# @Author : Luminous11 (573728051@qq.com)
*# @Date : 2015-04-20 18:38:59
*# @Link : http://blog.csdn.net/luminous11
***********************************************
*/
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#define clr(a, v) memset( a , v , sizeof(a) )
using namespace std;
const double eps = 1e-10;
//const double pi = acos(-1.0);
int g[2005][2005];
char str[2005][10];
int prim ( int n )
{
int ans = 0;
int dis[2005];
int vis[2005] = { 0 };
for ( int i = 0; i < n; i ++ ){
dis[i] = g[0][i];
}
for ( int k = 0; k < n; k ++ ){
int _min = 0x3f3f3f3f;
int p = -1;
for ( int i = 0; i < n; i ++ ){
if ( ! vis[i] && _min > dis[i] ){
_min = dis[i];
p = i;
}
}
if ( p == -1 )return -1;
vis[p] = 1;
ans += dis[p];
for ( int i = 0; i < n; i ++ ){
if ( ! vis[i] && dis[i] > g[p][i] ){
dis[i] = g[p][i];
}
}
}
return ans;
}
int main()
{
int n;
while ( cin >> n && n ){
clr ( g, 0 );
for ( int i = 0; i < n; i ++ ){
scanf ( "%s", str[i] );
}
for ( int i = 0; i < n; i ++ ){
for ( int j = i; j < n; j ++ ){
int len = 0;
for ( int k = 0; k < 7; k ++ ){
if ( str[i][k] != str[j][k] ){
len ++;
}
}
g[i][j] = g[j][i] = len;
}
}
int ans = prim( n );
cout << "The highest possible quality is 1/" << ans << "." << endl;
}
return 0;
}