IT民工
加油!

将字符串0n编号,然后建图。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;
}

 

 

 

posted on 2012-07-24 10:41  找回失去的  阅读(182)  评论(0编辑  收藏  举报