zoukankan      html  css  js  c++  java
  • POJ-1062 昂贵的聘礼 解题报告

    Dijstra算法

    题目链接: POJ-1062 昂贵的聘礼

    解题思路

    通过题意,我们可以很明显的看出来,物品的交换流程可以构成一个有向图,而且这个图是有边权的。

    构建这个图的过程如下:
    因为每个物品都有相应的替代物品,所以我们可以在替代物品和该物品之间建立一条边,从替代物品指向该物品,并且边上的权值为优惠价格。这样建完所有的边之后,我们可以创造一个起点,这个起点对所有的物品都有一个出边,并且边上的权值为该物品的原价。最终我们的结果肯定是一个从起点到编号为1的物品的最短路。

    通过上面的分析,现在我们的问题是如何将每个物品主人的等级考虑进去,根据题意我们了解到,我们最终的结果是在那条最短路上,最高的等级与最低的等级之间的差不能超过M,这里是特别容易弄错的地方,我之前以为是如果A与B之间的等级差小于M,B与C之间的等级差小于M就能一直从A交换到C……

    解题关键:最终的我们得到的最短路,里面肯定是有一个点X的等级是最低的,那么我们可以在原图上找到所有的比这个X点等级高的,而且那些点与X点之间的等级差必须小于等于M,最终的路径肯定是这些点里面产生的。所以我们枚举每一个可能的点,将这个被枚举的点当作X点,然后找到所有满足上述条件的其他点,在这些点之间跑单源最短路。每次枚举X点我都能得到一个最短路径值,最终我们取最小的路径值便是结果。

    解题代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int MAXN = 110;
    const int INF = 0X3fffffff;
    
    int M,N;
    int dis[MAXN][MAXN];
    int cost[MAXN];
    bool vis[MAXN];
    struct Node {
        int price;
        int level;
        int itemCount;
        int itemNum[MAXN];
        int itemPrice[MAXN];
    }node[MAXN];
    
    void initDis() {
        for(int i = 0; i <= N; i++) {
            dis[i][i] = 0;
            for(int j = i+1; j <= N; j++) {
                dis[i][j] = dis[j][i] = INF;
            }
        }
    }
    void initCost() {
        cost[0] = 0;
        for(int i = 1; i <= N; i++) {
            cost[i] = INF;
        }
    }
    
    void buildGraph() {
        for(int i = 1; i <= N; i++) {
            dis[0][i] = node[i].price;
            for(int j = 0; j < node[i].itemCount; j++) {
                int id = node[i].itemNum[j];
                int val = node[i].itemPrice[j];
                dis[id][i] = val;
            }
        }
    }
    
    int dijkstra(int x) {
        memset(vis, false, sizeof(vis));
        initCost();
        for(int i = 1; i <= N; i++) {
            if(node[x].level <= node[i].level && node[i].level-node[x].level <= M) {
                cost[i] = dis[0][i];
            }
        }
        vis[0] = true;
        for(int i = 1; i <= N; i++) {
            int _min = INF;
            int p = -1;
            for(int j = 0; j <= N; j++) {
                if(!vis[j] && _min > cost[j]) {
                    p = j;
                    _min = cost[j];
                }
            }
            if(-1 == p || INF == _min)continue;
            vis[p] = true;
            for(int j = 0; j <= N; j++) {
                if(!vis[j] && cost[j] > cost[p]+dis[p][j] &&
                   node[x].level <= node[j].level && node[j].level-node[x].level <= M) {
                    cost[j] = cost[p]+dis[p][j];
                }
            }
        }
        return cost[1];
    }
    
    int main() {
        while(~scanf("%d%d", &M, &N)) {
    
            initDis();
    
            for(int i = 1; i <= N; i++) {
                scanf("%d%d%d", &node[i].price, &node[i].level, &node[i].itemCount);
                for(int j = 0; j < node[i].itemCount; j++) {
                    scanf("%d%d", &node[i].itemNum[j], &node[i].itemPrice[j]);
                }
            }
    
            buildGraph();
    
            int ans = INF;
            for(int i = 1; i <= N; i++) {
                ans = min(dijkstra(i), ans);
            }
    
            printf("%d
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    【雕爷学编程】MicroPython动手做(01)——春节后入手了K210开发板
    【雕爷学编程】零基础Python(01)---“投机取巧”的三条途径
    【雕爷学编程】Arduino动手做(64)---RGB全彩LED模块
    Microsoft Development Platform Technologies
    JS 的Date对象
    SQL数据库连接池与C#关键字return
    RDLC报表 报表数据 栏 快捷键
    C# 操作World生成报告
    SAP-ABAP系列 第二篇SAP ABAP开发基础
    SAP-ABAP系列 第一篇SAP简介
  • 原文地址:https://www.cnblogs.com/yinzm/p/5937219.html
Copyright © 2011-2022 走看看