洛谷P1194:促销策略下的最优购物方案 最小生成树应用

深度学习
• 阅读 26

洛谷P1194:促销策略下的最优购物方案 最小生成树应用

一、问题分析

题目描述了一个促销场景:购买B件相同价格A元的商品,但购买特定组合(I,J)时可以享受优惠价K_{I,J}。我们需要计算购买所有商品的最小总花费。

二、算法选择

这个问题可以转化为图论中的最小生成树问题:

  1. 将每件商品视为中的一个节点
  2. 优惠价格K_{I,J}视为节点I和J之间的边权
  3. 添加一个虚拟节点0,连接到所有商品节点,边权为A

这样,原问题就转化为在这个图中找最小生成树,总权重即为最小花费。

三、C++代码实现

#include <iostream>
#include <vector>
#include <algorithm>
using namespACe std;

struct Edge {
    int u, v, w;
    bool operator<(const Edge& other) const {
        return w < other.w;
    }
};

vector<int> parent;

int find(int x) {
    return parent[x] == x ? x : parent[x] = find(parent[x]);
}

int main() {
    int A, B;
    cin >> A >> B;

    vector<Edge> edges;

    // 添加虚拟节点0到各商品的边
    for (int i = 1; i <= B; ++i) {
        edges.push_back({0, i, A});
    }

    // 读入优惠价格
    for (int i = 1; i <= B; ++i) {
        for (int j = 1; j <= B; ++j) {
            int k;
            cin >> k;
            if (i < j && k != 0) {  // 避免重复添加
                edges.push_back({i, j, k});
            }
        }
    }

    // Kruskal算法准备
    sort(edges.begin(), edges.end());
    parent.resize(B + 1);
    for (int i = 0; i <= B; ++i) parent[i] = i;

    int total = 0, count = 0;
    for (auto& e : edges) {
        int rootU = find(e.u);
        int rootV = find(e.v);
        if (rootU != rootV) {
            parent[rootV] = rootU;
            total += e.w;
            if (++count == B) break;  // 生成树有B条边
        }
    }

    cout << total << endl;
    return 0;
}

四、代码解析

  1. 数据结构:使用Edge结构体存储边信息
  2. 虚拟节点:节点0代表不适用任何优惠的原始购买方式
  3. 并查集:用于高效判断环的存在
  4. Kruskal算法:按边权排序贪心选择最小边

来源:编程学习

点赞
收藏
评论区
推荐文章
西八老码 西八老码
4年前
今天就来花一点时间整理一下算法吧!
算法,就是计算机处理信息的一个步骤。是独立存在的一种处理问题的方法和思想,并不局限于具体的实现过程。排序冒泡cpublicstaticintBubbleSort(intarr)for(inti0;i<arr.length;i)for(intj0;j<a
Wesley13 Wesley13
3年前
java b2b2c商城
一、需求分析1.买家可以对商品提交购买问题咨询,买家提交的商品购买咨询不单单商家可以进行回复,也应该可以将问题推送给购买过此商品的买家来进行回复。2.买家提出的咨询和对其他买家咨询的回复,都应该推送消息给相应的会员用户,做到及时提醒。二、流程图!在这里插入图片描述(https://img
Kubrnete Kubrnete
4年前
完全背包问题
问题描述有n种物品和一个容量为c的背包,每种物品都就可以选择任意多个,第i种物品的价值为v\i\,体积为w\i\,求解:在不超过背包容量的情况下,选择放入哪些物品能够使得背包中的价值最大?跟01背包一样,完全背包也是一个很经典的动态规划问题,不同的地方在于01背包问题中,每件物品最多选择一件;而在完全背包问题中,只要背包装得下,每件物品可
Stella981 Stella981
3年前
Codeforces 1208F Bits And Pieces 位运算 + 贪心 + dp
题意:给你一个序列a,问a\i\^(a\j\&a\k\)的最大值,其中i<j<k。思路:我们考虑对于每个a\i\求出它的最优解。因为是异或运算,所以我们从高位向低位枚举,如果这一位a\i\是0,我们就在a\i\的右边找两个位置让它们按位与起来这位是1。那么,我们贪心的保留可以通过按位与凑出某个二进制数的最靠右的两
Wesley13 Wesley13
3年前
TZOJ 2722 Matrix(树状数组区间取反单点查询)
描述GivenanN\NmatrixA,whoseelementsareeither0or1.A\i,j\meansthenumberintheithrowandjthcolumn.InitiallywehaveA\i,j\0(1<i,j<N).
贾蔷 贾蔷
23小时前
洛谷P3365 改造二叉树:从问题分析到代码实现
一、问题分析题目要求我们计算将修改为(BST)所需的最少修改次数。二叉搜索树的性质是:对于任意节点,其左子树所有节点的值都小于该节点的值,右子树所有节点的值都大于该节点的值。二、解题思路1.‌序列‌:BST的中序遍历结果是一个严格1.‌问题转化‌:将原二叉
Python实现根据商品ID获取蘑菇街商品详情数据,蘑菇街商品详情接口,蘑菇街API接口
蘑菇街是一家跨境电商网站,提供各种时尚、家居、美妆和电子产品等商品。在蘑菇街的商品详情页面,你可以看到以下信息:商品图片:展示商品的外观和细节,可以放大查看。商品名称:描述商品的名称,有时包含品牌和型号。商品价格:显示商品的售价,可能会包括促销价和折扣码。
贾蔷 贾蔷
2星期前
力扣120题终极攻略:动态规划解三角形最小路径和(C++实现)
一、问题描述给定一个三角形triangle,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的节点上。二、​​C​​解决方案(带注释)CincludeincludeusingnamespACestd;classSolutionpublic:i
深度学习 深度学习
2星期前
【CSP-S 2019】括号树(洛谷P5658):栈+DFS
一、题目解读括号树问题(洛谷P5658)要求处理一个由括号序列转化的树结构:每个节点表示一个括号,'('为子节点,')'为父节点。题目给定一棵n个节点的树,需计算每个节点的深度(括号层数),并输出所有节点深度与节点编号乘积的异或和。核心在于将括号序列转化为
深度学习 深度学习
2星期前
洛谷1111题解:基于Kruskal算法与并查集的最小生成树实现
一、题目解读洛谷1111题是一道经典的图论问题,要求构建一个无向图的最小生成树,并输出其最大边权值。题目核心在于通过给定的边集合,找到连接所有节点的最小权值子集,同时保证无环。这通常涉及最小生成树算法(如Kruskal)的应用,需要高效处理边权重与节点连通