E. Cheap Dinner (multiset 有手就行)

题意
给定 n 1 n_1 n1 种第一道菜的价格 a i a_i ai, n 2 n_2 n2 种第二道菜的价格 b i b_i bi, n 3 n_3 n3种饮料的价格 c i c_i ci, n 4 n_4 n4 种甜点的价格 d i d_i di
m 1 m_1 m1 种组合 ( x i , y i ) (x_i,y_i) (xi,yi), 描述编号为 x i x_i xi 的第一道菜与编号为 y i y_i yi 的第二道菜不能搭配
m 2 m_2 m2 种组合 ( x i , y i ) (x_i,y_i) (xi,yi), 描述编号为 x i x_i xi 的第二道菜与编号为 y i y_i yi 的饮料不能搭配
m 3 m_3 m3 种组合 ( x i , y i ) (x_i,y_i) (xi,yi), 描述编号为 x i x_i xi 的饮料与编号为 y i y_i yi 的甜点不能搭配
问是否能够每种种类的食物都分别挑选一种, 它们可以互相搭配且总花费最小

一眼过去,这tm不是大水题么
我把前一道菜的价格都扔进multiset里面,然后当查询到当前第 i i i 道菜时把限制了的菜都erase掉,然后获取前一道可行的菜最小的价格后,再把刚才erase掉的菜再加回去就可以了嘛
然后WA17 WA17 WA17
后来想到我erase的时候把

mt[now].erase(mt[now].find(a[now-1][to]));//删除当前菜有禁止的前菜价格
写成
mt[now].erase(a[now-1][to]);

改完就A了
然后这删除操作都写错了还能过17个test,我就去查了一下,原来multiset的删除是这样的

erase(iterator)  ,删除定位器iterator指向的值
erase(first,second),删除定位器first和second之间的值
erase(key_value),删除键值key_value的所有值

也就是说,如果我当前的multiset为<1,2,3,3,3,4,4>

set.erase(set.find(3)),即删除一个3,结果为<1,2,3,3,4,4>
set.erase(key_value),即删除所有3<1,2,4,4>

代码

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define memarray(array,val) memset(array,val,sizeof(array))
const int MAXN = 2e5+10;
int n[5];
int m[5];
long long a[5][MAXN];
multiset<long long>mt[6];
vector<int>vec[5][MAXN];
void solve(){
    for(int i=1;i<=n[1];i++)//把第一道菜的价格扔进multiset中
        mt[2].insert(a[1][i]);
    for(int now=2;now<=4;now++){
        for(int i=1;i<=n[now];i++){//遍历当前菜
            for(auto to:vec[now][i]){//将有限制的前菜价格erase掉
                mt[now].erase(mt[now].find(a[now-1][to]));
            }
            if(!mt[now].empty())a[now][i]+=*mt[now].begin();//如果非空则取最小价格更新价格
            else a[now][i]=1e9;//否则随便设一个最大值
            mt[now+1].insert(a[now][i]);//当前菜价格扔进下一个multiset里等下一轮
            for(auto to:vec[now][i]){//将有限制的前菜价格加回来
                mt[now].insert(a[now-1][to]);
            }
        }
    }
    if(!mt[5].empty()&&(*mt[5].begin())<5e8){//判断是否无解
        printf("%lld\n",*mt[5].begin());
    }else{
        printf("-1\n");
    }
}
void init(){
    for(int i=1;i<=4;i++)
        scanf("%d",n+i);
    for(int i=1;i<=4;i++)
        for(int j=1;j<=n[i];j++)
            scanf("%lld",a[i]+j);
    int x,y;
    for(int i=2;i<=4;i++){
        scanf("%d",m+i);
        for(int j=1;j<=m[i];j++){
            scanf("%d%d",&x,&y);
            vec[i][y].pb(x);
        }
    }
}
int main() {
    int T=1;
    while(T--){
        init();
        solve();
    }
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值