题意
给定 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;
}