将字符串0到n编号,然后建图。G[i][j] 是边的权值等于两个字符串的差异。然后求出最小生成树的权
值。第一次写堆优化的prim算法,堆优化的好处在于避免重复更新已经存在在生成树中的点的值,
在n比较大的时候效果会很明显。
/*Accepted 16128K 610MS C++ 1519B 2012-07-24 10:34:28*/ #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<cstdlib> #include<iostream> using namespace std; const int MAXN = 1 << 11; const int inf = 0x3f3f3f3f; int g[MAXN][MAXN], n; char buf[MAXN][8]; typedef pair<int, int> pii; int cal( int a, int b) { int i, ans = 0; for( i = 0; i < 7; i ++) { ans += ( buf[a][i] != buf[b][i]); } return ans; } void Read_Gragh() { int i, j; for( i = 0; i < n; i ++) { scanf( "%s", buf[i]); for( j = 0; j < i; j ++) { g[i][j] = g[j][i] = cal(i, j); } } } int prim() { priority_queue< pii, vector<pii>, greater<pii> > q; q.push( pii( 0, 0)); bool vis[MAXN] = {false}; int res = 0, i, p, lowc[MAXN]; for( i = 1; i < n; i ++) lowc[i] = inf; while( !q.empty() ) { while( !q.empty() && vis[ q.top().second]) q.pop(); if( q.empty() ) return res; p = q.top().second; q.pop(); res += lowc[p]; vis[p] = true; for( i = 0; i < n; i ++) { if( !vis[i] && lowc[i] > g[p][i]) { lowc[i] = g[p][i]; q.push( pii(lowc[i], i)); } } } return res; } int main() { while( scanf( "%d", &n) == 1) { if( n == 0) break; Read_Gragh(); printf( "The highest possible quality is 1/%d.\n", prim()); } return 0; }