[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;
    }
}

相关文章: