poj1062 Bellman 最短路应用

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

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

//这道是中文题,我居然还理解错了题意.本题的等级差是指  : 最高等级与最低等级的差值,并非每两个人之间的差值.

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <vector>
#define ll long long
#define inf 0x3f3f3f3f

using namespace std;
int n,m;
struct node{
    int p;
    int l;
    int x;
}a[110];
struct Nd{
    int num;
    int money;
}now;
int s,e;
vector<Nd>vec[110];
int vis[110];
int dis[110];
int ans;
void spfa(){
    memset(vis,0,sizeof(vis));
    memset(dis,inf,sizeof(dis));
    queue<int>q;
    q.push(1);
    vis[1] = 1;
    dis[1] = a[1].p;
    while(!q.empty()){
        int u = q.front();
        q.pop();
        vis[u] = 0;
        for(int i = 0; i < vec[u].size(); ++i){
            now = vec[u][i];
            if(dis[now.num] > dis[u]-a[u].p+a[now.num].p+now.money&&a[now.num].l>=s && a[now.num].l<=e){
                dis[now.num] = dis[u]-a[u].p+a[now.num].p+now.money;
                if(!vis[now.num]){
                    vis[now.num] = 1;
                    q.push(now.num);
                }
            }
        }
    }
    for(int i = 1; i <= n; ++i){
        ans = min(ans,dis[i]);
    }
}
int main()
{
    while(~scanf("%d%d",&m,&n)){
        for(int i = 0; i <= n; ++i){
            vec[i].clear();
        }
        
        for(int i = 1; i <= n; ++i){
            scanf("%d%d%d",&a[i].p,&a[i].l,&a[i].x);
            for(int j = 0; j < a[i].x; ++j){
                scanf("%d%d",&now.num,&now.money);
                vec[i].push_back(now);
            }
        }
        
        ans = inf;
        for(int i = a[1].l-m; i <= a[1].l; ++i){
            s = i;
            e = i+m;
            spfa();
        }
        printf("%d
",ans);
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#define INF 200000000

using namespace std;

struct node
{
    int u,v,w;
} edge[10000];
int num=0;
int N,M;
int P[2000],L[2000],n[2000];
int t,v;
int low[2000],a,b;
int has[2000] ;
int Bellman(int u0)
{
    for(int i=0; i<=N; i++)
        low[i]=INF;

    low[u0]=0;
    for(int i=0; i<N-1; i++)
    {
        int flag=0;
        for(int j=0; j<num; j++)
        {
            if(has[edge[j].u]&&has[edge[j].v]&&low[edge[j].u]+edge[j].w<low[edge[j].v])
            {
                low[edge[j].v]=low[edge[j].u]+edge[j].w;
                flag=1;
            }
        }
        if(flag==0)
            break;
    }

    int Min=INF;
    for(int i=1; i<=N; i++)
    {
        low[i]+=P[i];        //最小价格为优惠价+拥有优惠价须要花多少钱
        if(Min>low[i])
            Min=low[i];
    }
    //printf("%d
",Min);
    return Min; 
}
int main()
{
    //freopen("in.txt","r",stdin);
    while(~scanf("%d%d",&M,&N))
    {
    	num=0;
        for(int i=1; i<=N; i++)
        {
            scanf("%d%d%d",&P[i],&L[i],&n[i]);
            for(int j=1; j<=n[i]; j++)
            {
			    int a,b;
                scanf("%d%d",&a,&b);
                edge[num].u=i;
				edge[num].v=a;
				edge[num++].w=b;       //存入优惠的价格
            }
        }
        int ans=L[1];
        int Min=INF;
        //最高等级的与最低的等级差不会超过M
        for(int i=0; i<=M; i++)
        {
            memset(has,0,sizeof(has));
            for(int j=1; j<=N; j++)
            {
                if(ans-L[j]<=M-i&&L[j]-ans<=i)
                {
                    has[j]=1;
                }
            }
            int k=Bellman(1);
            if(Min>k)
				Min=k;
        }
        printf("%d
",Min);        

    }
}


原文地址:https://www.cnblogs.com/jzssuanfa/p/7061618.html