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

来源:互联网 发布:artrage中文版 mac 编辑:程序博客网 时间:2024/05/18 20:08

【题目来源】: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 0x3f3f3f3fusing 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;}