POJ 1062(dijkstra+思维)

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

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

存在等级关系,而且酋长不是等级最高的,这个只需要遍历就可以解决

建从1到其他点的有向图,且当直接距离超过了m,便不能建图

当求出最短路时候,遍历每一个d[i]+=a[i].val(商品价值)

OK

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <iomanip>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <vector>
//const int maxn = 1e5+5;
#define ll long long
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}

#define MAX INT_MAX
#define FOR(i,a,b) for( int i = a;i <= b;++i)
#define bug cout<<"--------------"<<endl
using namespace std;
int n,m,tot;
int ver[11000],edge[11000],next[11000],head[11000],vis[11000],d[11000];
vector<pair<int,int> >vec[500];
struct node
{
    int val,w,nub;
}a[500];
void add(int x,int y,int z)
{
    ver[++tot] = y,edge[tot] = z,next[tot] = head[x],head[x] = tot;
}
int dijiestra(int l,int r)
{
    priority_queue<pair<int,int> >que;
    memset(vis,0,sizeof(vis));
    memset(d,0x3f,sizeof(d));
    d[1] = 0;
    que.push(make_pair(0,1));
    while(que.size())
    {
        int x = que.top().second;que.pop();
        if(vis[x] == 1) continue;
        vis[x] = 1;
        for(int i= head[x];i;i=next[i])
        {
            int y = ver[i],z = edge[i];
            if( d[y] > d[x] + z && a[y].w>=l && a[y].w<=r)
            {
                d[y] = d[x] + z;
                que.push(make_pair(-d[y],y));
            }
        }
    }
    int minn = 9999999;
    for(int i = 1;i<=n;++i)
    {
        if(a[i].w>=l && a[i].w<=r)
        {
            minn=min(minn,d[i]+a[i].val);
        }
    }
    return minn;
}
int main()
{

      ios::sync_with_stdio(false);
    cin>>m>>n;
    for(int i=1;i<=n;++i)
    {
        cin>>a[i].val>>a[i].w>>a[i].nub;
        for(int j=1;j<=a[i].nub;++j)
        {
            int x,y;
            cin>>x>>y;
            vec[i].push_back(make_pair(x,y));
        }
    }
    for(int i=1;i<=n;++i)
    {
        for(int j=0;j<vec[i].size();++j)
        {
            int y = vec[i][j].first;
            int z = vec[i][j].second;
            if(abs(a[i].w-a[i].w) > m) continue;
            add(i,y,z);
        }
    }
    int temp = a[1].w;
    int minn  = 99999999;
    for(int i=temp-m;i<=temp;++i)
    {
        minn=min(minn,dijiestra(i,i+m));
    }
    cout<<minn<<endl;

}

 

 
posted @ 2019-08-18 00:26  阿斯水生产线  阅读(232)  评论(0编辑  收藏  举报