POJ-1062(原始dijiksra算法+思维)

昂贵的婚礼

POJ-1062

  • 这道题目一开始看的时候难以理解,但是仔细想,还是可以和最短路联系的,我觉得类似于硬币交换等问题。
  • 以下需要注意几个点,第一就是因为题目规定如何和超出了等级限制的人交易,则拒绝交易。也就是说符合交易条件的人一定和第一个人(国王)之间的等级差距小于m。
  • 这里通过枚举等级差距的方法来限制每次交易的人的总体的最大等级差距之差。加入一开始人的等级是3,而限制的等级差距是2,那么以下情况符合:1-3,2-4,3-5.也只有参加交易中的人的等级在这里面才能交易成功。
  • 所以,可以分别对这三种差距进行枚举,然后运行dijikstra算法,取最短的一个。
  • 还需要注意的是答案并不是直接求出来的最短路径。这里求解出来的知识优惠的价格而已,这里还要加上该结点的价格,也就是实际给钱的结点的价格才是最后答案。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
using namespace std;
const int maxn=102;
const int INF=0X3F3F3F3F;
int m,n;
int price[maxn];
int level[maxn];
int map[maxn][maxn];//map[i][j]表示物品i,j之间可以交换时的优惠价
bool vis[maxn];
int d[maxn];
void dijikstra(int s){
    memset(d,INF,sizeof(d));
    d[s]=0;
    for(int i=1;i<=n;i++){
        int v=-1;
        int mins=INF;
        for(int j=1;j<=n;j++){
            if(!vis[j]&&mins>d[j]){//
                v=j;
                mins=d[j];
            }
        }
        if(v==-1)
            break;
        vis[v]=1;
        for(int j=1;j<=n;j++){
            if(!vis[j]&&d[j]>d[v]+map[v][j]){
                d[j]=d[v]+map[v][j];
            }
        }
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    while(cin>>m>>n){
        memset(map,INF,sizeof(map));
        for(int i=1;i<=n;i++){
            //int p,l,x;//物品的价格、主人的地位等级和替代品总数
            int x;
            cin>>price[i]>>level[i]>>x;
            for(int j=0;j<x;j++){
                int num,discount;
                cin>>num>>discount;//替代品的编号和"优惠价格"
                map[i][num]=discount;
            }
        }
        int mins=INF;
        for(int i=0;i<=m;i++){//这里枚举等级,将所有的情况枚举出来,就是符合这个的等级区间的不同情况
            memset(vis,0,sizeof(vis));
            for(int j=1;j<=n;j++){
                if(level[1]-m+i>level[j]||level[1]+i<level[j]){//m表示等级限制
                    vis[j]=true;
                }
            }
            dijikstra(1);
            for(int j=1;j<=n;j++){//求出的最短路径还要加上直接交钱给该结点的价格,因为最短路是优惠的总价格。
                mins=min(mins,price[j]+d[j]);
                //cout<<d[j]<<endl;
            }
        }
        cout<<mins<<endl;
    }
    return 0;
}

转载于:https://www.cnblogs.com/GarrettWale/p/11469026.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值