POJ 1062 昂贵的聘礼

这道题比较经典了。建图时用g[0][i] 表示不用替代物品获得编号为i的物品所需的金币,

g[j][i]代表用编号为j的物品替代获得编号为i的物品所需要的金币,然后在M的限制范

围内进行所有可能的交易,最后获得其最小值,一共需要做mdij

 

/*Accepted    228K    0MS    C++    1600B    2012-07-26 15:16:49*/

#include<cstdio>

#include<cstring>

#include<cstdlib>

#include<algorithm>

#include<queue>

using namespace std;

const int MAXN = 1 << 7;

const int inf = 0x3f3f3f3f;

int M, N, g[MAXN][MAXN], lev[MAXN];

typedef pair< int, int> pii;



void ReadGragh()

{

    for( int i = 0; i <= N; i ++)

        for( int j = 0; j <= N; j ++)

            g[i][j] = inf;



    for( int i = 1; i <= N; i ++)

    {

        int x;

        scanf( "%d%d%d", &g[0][i], &lev[i], &x);

        while( x --)

        {

            int j;

            scanf( "%d", &j);

            scanf( "%d", &g[j][i]);

        }

    }

}



int Dijkstra( int l, int r)

{

    priority_queue< pii, vector<pii>, greater<pii> > q;

    int dist[MAXN] = {0};

    for( int i = 1; i <= N; i ++)

        dist[i] = inf;

    q.push( make_pair(0, 0) );

    while( !q.empty() )

    {

        pii u = q.top(); q.pop();

        int x = u.second;

        if( u.first > dist[x]) continue;

        if( x == 1) return dist[1];

        for( int i = 1; i <= N; i ++)

        {

            if( l <= lev[i] && lev[i] <= r && dist[i] > dist[x] + g[x][i])

            {

                dist[i] = dist[x] + g[x][i];

                q.push( make_pair( dist[i], i));

            }

        }

    }

    return 0;

}



int main()

{

    int ans;

    while( scanf( "%d%d", &M, &N) == 2)

    {

        ans = inf;

        ReadGragh();

        for( int i = lev[1] - M; i <= lev[1]; i ++) //在M的范围内交易

        {

            ans = min( ans, Dijkstra( i, i + M) );

        }

        printf( "%d\n", ans);

    }

    return 0;

}

 

 

 

你可能感兴趣的:(poj)