传送门


被题意杀

本以为一个种类的物品一定要一起买

看了题解才知道可以先把所有要买的物品买一个,剩下要买的物品就可以得到这个种类的物品能够得到的最大优惠……

所以现在只需要知道:第一次买所有物品一遍时按照什么顺序买最优惠

建一个超级源点向每一个物品连权值等同于其价值的边,对于优惠\((A,B,P)\)从\(A\)向\(B\)连权值为\(P\)的遍,然后一遍最小树形图即可。

注意一个购买数量为\(0\)的点和它的所有出入边都要被忽视

#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;

struct Edge{
    int s , t;
    double w;
}Ed[5010];
int id[101] , vis[101] , num[101] , pre[101];
int N , M , cntEd;
double sum , pri[101] , dis[101];
bool have[101][101];

void work(int rt){
    while(1){
        memset(vis , 0x3f , sizeof(vis));
        memset(id , -1 , sizeof(id));
        fill(dis , dis + N + 1 , 5e7);
        int cnt = 0;
        for(int i = 1 ; i <= cntEd ; ++i)
            if(Ed[i].s != Ed[i].t && dis[Ed[i].t] > Ed[i].w){
                dis[Ed[i].t] = Ed[i].w;
                pre[Ed[i].t] = Ed[i].s;
            }
        for(int i = 0 ; i <= N ; ++i){
            if(i == rt)
                continue;
            sum += dis[i];
            int u = i;
            vis[i] = i;
            while(u != rt && vis[pre[u]] > i)
                vis[u = pre[u]] = i;
            if(u != rt && vis[pre[u]] == i){
                do{
                    id[u] = cnt;
                    u = pre[u];
                }while(id[u] == -1);
                ++cnt;
            }
        }
        if(!cnt)
            break;
        for(int i = 0 ; i <= N ; ++i)
            if(id[i] == -1)
                id[i] = cnt++;
        for(int i = 1 ; i <= cntEd ; ++i){
            Ed[i].w -= dis[Ed[i].t];
            Ed[i].s = id[Ed[i].s];
            Ed[i].t = id[Ed[i].t];
        }
        N = cnt - 1;
        rt = id[rt];
    }
}

signed main(){
    #ifndef ONLINE_JUDGE
    //freopen("in" , "r" , stdin);
    //freopen("out" , "w" , stdout);
    #endif
    cin >> N;
    for(int i = 1 ; i <= N ; ++i){
        cin >> pri[i] >> num[i];
        Ed[++cntEd].s = 0;
        Ed[cntEd].t = i;
        if(num[i])
            Ed[cntEd].w = pri[i];
    }
    cin >> M;
    for(int i = 1 ; i <= M ; ++i){
        int a , b;
        double c;
        cin >> a >> b >> c;
        if(num[a] && num[b]){
            Ed[++cntEd].s = a;
            Ed[cntEd].t = b;
            Ed[cntEd].w = c;
            pri[b] = min(pri[b] , c);
        }
    }
    for(int i = 1 ; i <= N ; ++i)
        if(num[i])
            sum += (num[i] - 1) * pri[i];
    work(0);
    cout << fixed << setprecision(2) << sum;
    return 0;
}

Luogu2792 JSOI2008 小店购物 最小树形图的更多相关文章

  1. 【LuoguP2792 】[JSOI2008]小店购物(最小树形图)

    题目链接 题目描述 小店的优惠方案十分简单有趣: 一次消费过程中,如您在本店购买了精制油的话,您购买香皂时就可以享受2.00元/块的优惠价:如果您在本店购买了香皂的话,您购买可乐时就可以享受1.50元 ...

  2. 洛谷P2792 [JSOI2008]小店购物(最小树形图)

    题意 题目链接 Sol 一开始的思路:新建一个虚点向每个点连边,再加上题面中给出的边,边权均为大小*需要购买的数量 然后发现死活都过不去 看了题解才发现题目中有个细节--买了\(A\)就可以买\(B\ ...

  3. Luogu2792 [JSOI2008]小店购物

    Luogu2792 [JSOI2008]小店购物 重题 bzoj4349 最小树形图 有 \(n\) 个物品,每个物品有价格 \(c_i\) 和所需个数 \(k_i\) ,所有物品必须恰好买 \(k_ ...

  4. [JSOI2008]小店购物 & bzoj4349:最小树形图 最小树形图

    ---题面(洛谷)--- ---题面(bzoj)--- 其实是同一道题,,,样例都一模一样 题解: 一开始看想了好久,,,还想到了最短路和最小生成树,,然而写的时候才意识到最小生成树应该要用无向边 其 ...

  5. JSOI2008 小店购物

    https://www.luogu.org/problem/show?pid=2792 题目背景 JSOI集训队的队员发现,在他们经常活动的集训地,有一个小店因为其丰富的经营优惠方案深受附近居民的青睐 ...

  6. 最小树形图--朱刘算法([JSOI2008]小店购物)

    题面 luogu Sol 首先设一个 \(0\) 号点,向所有点连边,表示初始价值 显然这个图的一个 \(0\) 为根的最小有向生成树的边权和就是每个买一次的最小价值 再买就一定能优惠(包含 \(0\ ...

  7. 【Bzoj2260】【Bzoj4349】商店购物 & 最小树形图

    目录 List Bzoj 2260 商店购物 Description Input Output Sample Input Sample Output Bzoj 4349 最小树形图 Descripti ...

  8. bzoj2260: 商店购物 && 4349: 最小树形图

    Description Grant是一个个体户老板,他经营的小店因为其丰富的优惠方案深受附近居民的青睐,生意红火.小店的优惠方案十分简单有趣.Grant规定:在一次消费过程中,如果您在本店购买了精制油 ...

  9. bzoj2260: 商店购物&&4349: 最小树形图

    最小树形图问题啊 最小树形图是撒哩,就是给你一个有向图,确定一个根,要你到达所有点,那棵最短路径树的总边权 做这个用的是朱(jv)刘(lao)算法. 首先假如有多个联通块就无解啦 对应每个点(除了根) ...

随机推荐

  1. python之初始面向对象

    1. 初识面向对象  面向过程: 一切以事务的发展流程为中心. 面向对象: 一切以对象为中心. 一切皆为对象. 具体的某一个事务就是对象 2. 类. 对象 类: 就是图纸. 创建对象的第一步. 先画图 ...

  2. js 乘除法小数问题

    因为经常需要js来处理显示,就做下笔记 除法: function accDiv(arg1, arg2) { var t1 = 0, t2 = 0, r1, r2; try { t1 = arg1.to ...

  3. 如今领占主导地位的19种AI技术!

    如今领占主导地位的19种AI技术! http://blog.itpub.net/31542119/viewspace-2212797/ 深度学习的突破将人工智能带进全新阶段. 2006 年-2015 ...

  4. linux之sort和uniq

    uniq uniq命令: uniq不加参数,只对相邻的相同行内容去重. 例子如下: [root@localhost ~]# pwd /root [root@localhost ~]# cat oldb ...

  5. 你的BI应用处于什么阶段?解读Gartner BI成熟度模型

    文 | 帆软数据应用研究院 水手哥 本文出自:知乎专栏<帆软数据应用研究院>——数据干货&资讯集中地   无论国内还是国外,多数企业的BI和分析平台建设之路并不平坦:一是对自身的环 ...

  6. 【转】MySQL:日期函数、时间函数总结(MySQL 5.X)

    转自:http://www.cnblogs.com/she27/articles/1377089.html 一.MySQL 获得当前日期时间 函数1.1 获得当前日期+时间(date + time)函 ...

  7. 第一个Django页面(2)

    第一个Django页面 1,进入forum项目:熟悉项目里各种文件的作用 2,配置URL:在urls.py里面添加 [url路径与对应的处理函数] 3,编写处理函数:根据urls.py里添加函数的路径 ...

  8. Python-初识模块

    #系统自带的模块 import sys print(sys.path)#打印环境变量 print(sys.argv)#打印绝对路径 import os #cmd_res = os.system(&qu ...

  9. Redis系列(二):Redis的数据类型及命令操作

    原文链接(转载请注明出处):Redis系列(二):Redis的数据类型及命令操作 Redis 中常用命令 Redis 官方的文档是英文版的,当然网上也有大量的中文翻译版,例如:Redis 命令参考.这 ...

  10. js,ajax,layer笔记(弹出层,在弹出一个弹框)

    整体认识: 因为作用域的问题,js 在页面初次加载时已近加载好了,所以要有第二次弹窗的效果,必须得在第一次成功之后再次让他加载js 代码: /*shaun*/showdetailsPag: funct ...