POJ 1062 昂贵的聘礼

题目链接:http://poj.org/problem?id=1062

/*
题意:输入M,N分别表示地位等级差距限制和物品的总数。
接下 输入 P L X 表示物品价格,主人等级,替代物品数目
替代物品:T,V表示 替代物品编号和优惠价格

M N
P1 L1 X1
T1 V1
P2 L2 X2
T2 V2

输出最少需要的金币数。

那么 在求最短路径时 需要保证  level[i]在 L1-M,L1+M之间
那么 在求最短路径时 需要保证  level[i]在 L1-M,L1+M之间
那么 在求最短路径时 需要保证  level[i]在 L1-M,L1+M之间
思路:
G[i][j] i表示替代物品编号,j表示物品的编号
相当于:物品为j的 所要求的替代物品编号是0.. i...
比如 10000 3 2
G[2][3]=8000
G[3][2]=5000;
其余值为INF表示不能达到
G[i][j]的值是 金币数


抽象成:
对于一个有向图:G[I][J] 表示起点i到终点j的权值是G[I][J]
现在表示的含义是:j替代物品 代替 了 物品 i 所需的金币数目是G[i][j]
原来dis[i]代表 起点到达i的最短路径是dis[i]
现在dis[i]代表     物品i被替代所需的最少金币数

起点为0 终点为1  因为有限制条件:等级需要在 L1-M,L1+M之间
用level数组存  level[i]表示拥有物品i的人物等级是level[i]
那么 在求最短路径时 需要保证  level[i]在 L1-M,L1+M之间
                                                                
*/



#include<cstdio>
#define INF 1000000000
const int N=112;
int G[N][N],dis[N];
int level[N];
void dijkstra(int l,int r,int n)
{
    int i,pos=0,j,min;
    bool vis[N]={0};
    for(int i=0;i<=n;++i) dis[i]=INF;
    for(int i=1;i<=n;++i) if(level[i]>=l&&level[i]<=r)
        dis[i]=G[pos][i];
    vis[pos]=true;
    for(i=1;i<n;++i)
    {
        for(j=1,min=INF;j<=n;++j)
        {
            if(level[j]>=l&&level[j]<=r&&!vis[j]&&dis[j]<min)
            {
                min=dis[j];
                pos=j;
            }
        }
            vis[pos]=true;

            for(j=1;j<=n;++j)if(!vis[j]&&level[j]>=l&&level[j]<=r){
                if(dis[j]>G[pos][j]+dis[pos]){
                    dis[j]=G[pos][j]+dis[pos];
                }
            }
        }
}
int main()
{
    int limit_level,total;
    int cnt;
    int ans=INF;
    int index,t_money;
    while(~scanf("%d %d",&limit_level,&total)){

        for(int i=0;i<=total;++i)
            for(int j=0;j<=total;++j) G[i][j]=INF;

        for(int k=1;k<=total;++k)
        {
                scanf("%d %d %d",&G[0][k],&level[k],&cnt);
                for(int i=0;i<cnt;++i)
                {
                    scanf("%d %d",&index,&t_money);
                    G[index][k]=t_money;// why is not G[k][index]?
                }
        }
        for(int i=level[1]-limit_level;i<=level[1];++i)
        {
                dijkstra(i,i+limit_level,total);
                if(ans>dis[1])
                    ans=dis[1];
        }
        printf("%d\n",ans);
    }

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值