POJ - 1062(昂贵的聘礼)(有限制的spfa最短路)

题意:。。。中文题。。。

昂贵的聘礼
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 54350   Accepted: 16368

Description

年轻的探险家来到了一个印第安部落里。在那里他和酋长的女儿相爱了,于是便向酋长去求亲。酋长要他用10000个金币作为聘礼才答应把女儿嫁给他。探险家拿不出这么多金币,便请求酋长降低要求。酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币。如果你能够弄来他的水晶球,那么只要5000金币就行了。"探险家就跑到大祭司那里,向他要求皮袄或水晶球,大祭司要他用金币来换,或者替他弄来其他的东西,他可以降低价格。探险家于是又跑到其他地方,其他人也提出了类似的要求,或者直接用金币换,或者找到其他东西就可以降低价格。不过探险家没必要用多样东西去换一样东西,因为不会得到更低的价格。探险家现在很需要你的帮忙,让他用最少的金币娶到自己的心上人。另外他要告诉你的是,在这个部落里,等级观念十分森严。地位差距超过一定限制的两个人之间不会进行任何形式的直接接触,包括交易。他是一个外来人,所以可以不受这些限制。但是如果他和某个地位较低的人进行了交易,地位较高的的人不会再和他交易,他们认为这样等于是间接接触,反过来也一样。因此你需要在考虑所有的情况以后给他提供一个最好的方案。 
为了方便起见,我们把所有的物品从1开始进行编号,酋长的允诺也看作一个物品,并且编号总是1。每个物品都有对应的价格P,主人的地位等级L,以及一系列的替代品Ti和该替代品所对应的"优惠"Vi。如果两人地位等级差距超过了M,就不能"间接交易"。你必须根据这些数据来计算出探险家最少需要多少金币才能娶到酋长的女儿。 

Input

输入第一行是两个整数M,N(1 <= N <= 100),依次表示地位等级差距限制和物品的总数。接下来按照编号从小到大依次给出了N个物品的描述。每个物品的描述开头是三个非负整数P、L、X(X < N),依次表示该物品的价格、主人的地位等级和替代品总数。接下来X行每行包括两个整数T和V,分别表示替代品的编号和"优惠价格"。

Output

输出最少需要的金币数。

Sample Input

1 4
10000 3 2
2 8000
3 5000
1000 2 1
4 200
3000 2 1
4 200
50 2 0

Sample Output

5250

Source

 
解析:
  看清题。。。:“如果他和某个地位较低的人进行了交易,地位较高的的人不会再和他交易”  下面关于探险家的那句纯属扯淡无用 看这句就好
这句也就说明了 交换的人只能在一个限定的等级区间里 最低是酋长的等级-m      最高是酋长的等级+m
所以从   酋长的等级-m 到 酋长的等级  枚举区间的下限  上限为下限+m
然后再每次最短路更新值时 判断一下即可
 
对了  我的路径权值是优惠了多少钱 。。。所以找的是最长路  最后用10000 - 优惠了的钱的最大值 = 优惠后的钱的最小值
 
#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define maxn 100009
#define Pair pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define _  ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int LL_INF = 0x7fffffffffffffff,INF = 0x3f3f3f3f;
int head[maxn], d[maxn], vis[maxn];
int n,m;
struct dot{
    int fd,sca,num;
}Dot[maxn];

struct node{
    int u,v,w,next;
}Node[maxn];

void add(int u,int v,int w,int i)
{
    Node[i].u = u;
    Node[i].v = v;
    Node[i].w = w;
    Node[i].next = head[u];
    head[u] = i;
}

void spfa(int s,int xia)
{
    queue<int> Q;
    mem(d,0);
    mem(vis,0);
    Q.push(s);
    vis[s] = 1;
    while(!Q.empty())
    {
        int x = Q.front(); Q.pop();
        vis[x] = 0;
        for(int i=head[x]; i!=-1; i=Node[i].next)
        {
            node e = Node[i];
            if(d[e.v] < d[x] + e.w - Dot[e.v].fd && abs(Dot[e.v].sca - Dot[x].sca) <= m && Dot[e.v].sca <= xia+m && Dot[e.v].sca >= xia)
            {
                d[e.v] = d[x] + e.w - Dot[e.v].fd;
                if(!vis[e.v])
                {
                    Q.push(e.v);
                    vis[e.v] = 1;
                }
            }
        }
    }
}
int main()
{
    int cnt = 0;
    cin>> m >> n;
    mem(head,-1);
    for(int i=1; i<=n; ++i)
    {
        cin>> Dot[i].fd >> Dot[i].sca >> Dot[i].num;
        for(int j=0; j<Dot[i].num; ++j)
        {
            int id, money;
            cin>> id >> money;
            add(i,id,Dot[i].fd - money,cnt++);
        }
    }

    int minn = -INF;
    for(int i=Dot[1].sca - m; i<=Dot[1].sca; i++){
        spfa(1,i);
        for(int i=1; i<=n; ++i){
            if(d[i] != INF)
                minn = max(minn,d[i]);
        }
    }
    cout<<Dot[1].fd-minn<<endl;
    return 0;
}
 

猜你喜欢

转载自www.cnblogs.com/WTSRUVF/p/9157665.html