POJ1062---昂贵的聘礼(最短路:题意。。)

【题目来源】https://vjudge.net/problem/POJ-1062
【题意】
题意很简单,就是要求买1号的东西,但是可以用规定的其他编号的东西代替,然后给出一个降低后的价格,但是呢,每件物品的主任具有等级的差距,也就是如果和等级4的交易后,若最大等级差距为2,那么任何情况下都不能再于等级1的交易。
【思路】
枚举一下差距的上限,因为如果一旦和等级4的交易了,若等级差距为2,那么在之后都不能与等级1的进行交易,所以要枚举。
我用的bellman,记录的是u,v端点的最多省多少钱,然后,找出最省钱的(一定是个负值)。
【代码】

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;
struct pp
{
    int u,v,w;
}edge[10001];
int ranks[101];
int mp[101][101];
int p[101];
int d[101];
int n,m,tot;

void add(int u,int v,int w)
{
    edge[tot].u = u;
    edge[tot].v = v;
    edge[tot++].w = w;
}

int BellMan(int h,int l)
{
    int u,v,w,mn=0;
    memset(d,INF,sizeof(d));
    d[1] = 0;
    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j < tot; ++j)
        {
            u = edge[j].u;
            v = edge[j].v;
            w = edge[j].w;
            if(d[v] > d[u] + w && ranks[v] >= l && ranks[v] <= h)
            {
                d[v] = d[u] +w;
                if(d[v]<mn)
                    mn=d[v];
            }
        }
    }
    return mn;
}
int main()
{
    tot = 0;
    int x,v,l,w;
    scanf("%d %d",&m,&n);
    memset(mp,INF,sizeof(mp));
    int minn = 0;
    for(int i = 1; i <= n; ++i)
    {
        scanf("%d %d %d",&p[i],&ranks[i],&x);
        while(x--)
        {
            scanf("%d %d",&v,&w);
            add(i,v,w);
        }
    }
    for(int i=0;i<tot;i++)//求能省多少钱
    {
        edge[i].w-=p[edge[i].u];
        edge[i].w+=p[edge[i].v];
    }
    for(int h = ranks[1]+m,l = ranks[1]; h >= ranks[1]; --h,--l)//枚举范围
    {
         minn = min(minn,BellMan(h,l));
    }
    printf("%d\n",minn+p[1]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值