[CF1487E] Cheap Dinner
Description
开胃菜,主菜,饮品和甜点,各一道组成一顿晚饭,第 i 种菜又 ni 道可以选择,其中第 j 道的价格为 aj,bj,cj,dj。有 m1 对开胃菜和主菜不能搭配,有 m2 对主菜和饮品不能搭配,有 m3 对饮品和甜点不能搭配。问总价格最小的晚饭需要多少钱。
Solution
对于 B,找到与他搭配的最小的 A
对于 C,找到与他搭配的最小的 D
然后在 BC 之间配对即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
ios::sync_with_stdio(false);
int sa, sb, sc, sd;
cin >> sa >> sb >> sc >> sd;
vector<int> a(sa), b(sb), c(sc), d(sd);
vector<int> mba(sb), mcd(sc);
for (int i = 0; i < sa; i++)
cin >> a[i];
for (int i = 0; i < sb; i++)
cin >> b[i];
for (int i = 0; i < sc; i++)
cin >> c[i];
for (int i = 0; i < sd; i++)
cin >> d[i];
vector<vector<int>> gba(sb), gbc(sb), gcd(sc);
int sz;
cin >> sz;
while (sz--)
{
int x, y;
cin >> x >> y;
--x;
--y;
gba[y].push_back(x);
}
cin >> sz;
while (sz--)
{
int x, y;
cin >> x >> y;
--x;
--y;
gbc[x].push_back(y);
}
cin >> sz;
while (sz--)
{
int x, y;
cin >> x >> y;
--x;
--y;
gcd[x].push_back(y);
}
multiset<int> ms;
for (int aid = 0; aid < sa; aid++)
{
ms.insert(a[aid]);
}
ms.insert(1e18);
for (int bid = 0; bid < sb; bid++)
{
for (auto t : gba[bid])
ms.erase(ms.find(a[t]));
mba[bid] = b[bid] + (*ms.begin());
for (auto t : gba[bid])
ms.insert(a[t]);
}
ms.clear();
for (int did = 0; did < sd; did++)
{
ms.insert(d[did]);
}
ms.insert(1e18);
for (int cid = 0; cid < sc; cid++)
{
for (auto t : gcd[cid])
ms.erase(ms.find(d[t]));
mcd[cid] = c[cid] + (*ms.begin());
for (auto t : gcd[cid])
ms.insert(d[t]);
}
ms.clear();
for (int cid = 0; cid < sc; cid++)
{
ms.insert(mcd[cid]);
}
ms.insert(1e18);
int ans = 1e18;
for (int bid = 0; bid < sb; bid++)
{
for (auto t : gbc[bid])
ms.erase(ms.find(mcd[t]));
ans = min(ans, mba[bid] + (*ms.begin()));
for (auto t : gbc[bid])
ms.insert(mcd[t]);
}
if (ans > 1e10)
{
cout << -1;
}
else
{
cout << ans;
}
}