POJ #1062 昂贵的聘礼 有限制的最短路 枚举+dijkstra求最短路

Description



  问题:链接

  更多的测试用例:POJ DISCUSS

思路



  这道题的关键点有两个:图的构建与物品能进行交换的等级区间。

  对于前一个问题,需要以探险家作为起始点,设其编号为0,暂且计各物品编号为顶点编号,物品为各顶点,由于探险家可以用金币买各个物品,所以 0 点可以直接到达其余各点,边的权为购买该物品的金币数;而物品 i 与物品 j 间可能进行交换,所以让 i -> j 表示用“物品 j + 物品 i 优惠后的价格 = 物品 i” 。而原问题—— ”探险家化最少的金币买到酋长的诺言“ 也就转换成了求 0 点 到 1 点的最短路。

  原问题在交换物品时还有另外一个要求:两两交换的物品的地位不能相差 M 且所有经交换的物品的地位不能相差 M 。顺着这个思路,我们一开始可能会以酋长为最高等级 level,取等级在区间 [ level - M, level ] 中的物品进行交换,而剔除区间之外的物品。但是忽略了一个问题:酋长可能不是最高等级! 这个问题也很好理解,比如酋长的爸爸、酋长的爷爷...等等的等级就可能比酋长还高。那么就会想把区间扩展到 [ level - M, level + M ]  。但是在这个区间中的两件物品相差可能会超过 M,比如等级为 level - M 的物品与 level + 1 的物品它们的等级差距为 M+1 。那么我们就需要从 [ level - M, level ] 开始到 [lev, lev + M ] 结束,穷举区间,记录最小的最短路。

  

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
#define INF 0x3f3f3f3f
int M, N; //最大等级差距与物品数
const int MAX_N = 110;
struct Edge{
    int to;
    int cost;
    Edge(int tt, int cc) : to(tt), cost(cc) {}
};
vector<Edge> G[MAX_N];

void addEdge (const int& u, const int& v, const int& w) {
    G[u].push_back(Edge(v, w));
}

struct Node{
    int id;
    int cost;
    friend bool operator < (const Node& a, const Node& b) {
        return a.cost > b.cost;
    }
}dis[MAX_N];
bool visit[MAX_N];
int level[MAX_N];
bool outlevel[MAX_N];
void dijkstra(const int& s) {
    for (int i = 0; i <= N; i++) dis[i].id = i, dis[i].cost = INF;
    dis[0].id = 0, dis[0].cost = 0;
    for (int i = 0; i <= N; i++) visit[i] = false;

    priority_queue<Node> pQueue;
    pQueue.push(dis[0]);
    while(!pQueue.empty()) {
        int u = pQueue.top().id; pQueue.pop();
        if (visit[u]) continue;
        visit[u] = true;
        for (int j = 0; j < G[u].size(); j++) {
            int v = G[u][j].to;
            int cost = G[u][j].cost;
            if (!outlevel[v] && dis[v].cost > dis[u].cost + cost ) {
                dis[v].cost =  dis[u].cost + cost;
                pQueue.push(dis[v]);
            }
        }
    }
}

int main(void) {
    cin >> M >> N;
    for (int i = 0; i <= N; i++) G[i].clear();
    for (int i = 1; i <= N; i++) {
        int P, L, X;
        cin >> P >> L >> X;
        level[i] = L;
        addEdge(0, i, P); //探险家可直接买物品
        //以物抵金币
        for (int j = 1; j <= X; j++) {
            int num, cost;
            cin >> num >> cost;
            addEdge (num, i, cost);
        }
    }
    //枚举每一个等级作为最小等级,在可交换的等级区间内求最短路
    int ans = INF;
    for (int i = 1; i <= N; i++) {
        //去除不可交换的等级区间内的物品
        for (int j = 1; j <= N; ++j) outlevel[j] = false;
        int min_level = level[i];
        for (int j = 1; j <= N; j++) {
            if (level[j] < min_level || min_level + M < level[j] )
                outlevel[j] = true; //第j个物品不可用于交换
        }
        dijkstra(0);
        ans = min(ans, dis[1].cost);
    }
    cout << ans << endl;
    return 0;
}

  

原文地址:https://www.cnblogs.com/Bw98blogs/p/8451428.html

时间: 2024-10-22 10:37:30

POJ #1062 昂贵的聘礼 有限制的最短路 枚举+dijkstra求最短路的相关文章

POJ - 1062昂贵的聘礼最短路或者DFS

POJ - 1062 昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000KB   64bit IO Format: %I64d & %I64u Submit Status Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币.如

POJ 1062 昂贵的聘礼 最短路

Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币.如果你能够弄来他的水晶球,那么只要5000金币就行了."探险家就跑到大祭司那里,向他要求皮袄或水晶球,大祭司要他用金币来换,或者替他弄来其他的东西,他可以降低价格.探险家于是又跑到其他地方,其他人也提出了类似的要求

poj 1062 -- 昂贵的聘礼

昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 35515   Accepted: 10163 Description 年 轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿 不出这么多金币,便请求酋长降低要求.酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币.如果你能够弄来他的水晶球,那么只要 5

poj 1062 昂贵的聘礼 解题报告

题目链接:http://poj.org/problem?id=1062 这一题只要想到如何建图,就不太难解决了.假设对于编号为 i 的物品,如果它得到物品 j 后价格从 pricei 降低到 pricej 的话,就用一个cost[i][j] = pricej.也就是从物品 i 到物品 j 连一条有向边.每一个编号的物品都这样处理,然后套用dijk 算法,求出从每个点出发的最短路,最终最小的那个就是答案.考虑到等级限制,别人可以跟酋长接触的前提是这个人的等级在 [ level 酋长-m  ~ le

POJ -1062 昂贵的聘礼(前向星 &amp;&amp; SPFA)

题目链接:昂贵的聘礼 这个题对自己收获挺大的,模板要自己经常敲,才能理解,要自己经常敲,从能温故而知新,自己以前总结的建图方式,做题的时候要会用,要敢用,否则==NULL. 题意对于交换条件描述的有点不清楚,这里解释一下,假设8件物品,等级差距不能超过3,酋长LV 5,所以可以进行交换的LV区间是[2,5][3,6][4,7][5,8],不必考虑题目那一句,"但是如果他和某个地位较低的人进行了交易,地位较高的的人不会再和他交易,他们认为这样等于是间接接触,反过来也一样".越看越晕,只要

poj 1062 昂贵的聘礼 (dijkstra最短路)

题目链接:http://poj.org/problem?id=1062 昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 36799   Accepted: 10616 Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:"嗯,如果你能够替我弄到大祭司的

poj 1062 昂贵的聘礼 (最短路)

poj 1062 昂贵的聘礼 Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币.如果你能够弄来他的水晶球,那么只要5000金币就行了."探险家就跑到大祭司那里,向他要求皮袄或水晶球,大祭司要他用金币来换,或者替他弄来其他的东西,他可以降低价格.探险家于是又跑到其他

POJ 1062 昂贵的聘礼(带限制条件的dijkstra)

题目网址:http://poj.org/problem?id=1062 题目: 昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 49916   Accepted: 14961 Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:"嗯,如果你能够替我弄到

poj 1062 昂贵的聘礼 Dijkstra算法,中等难度,,,一道让我累觉不爱的题目

昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 38474   Accepted: 11132 Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币.如果你能够弄来他的水晶球,那么只要5000