IT民工
加油!

这道题比较经典了。建图时用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;
}

 

 

 

posted on 2012-07-26 15:22  找回失去的  阅读(174)  评论(0编辑  收藏  举报