POJ 1789 Truck History

将字符串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;

}

 

 

 

你可能感兴趣的:(history)