码迷,mamicode.com
首页 > 其他好文 > 详细

【CF802C】Heidi and Library(网络流)

时间:2019-10-29 23:58:42      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:cos   queue   现在   main   make   add   题意   syn   sync   

codeforces

题意:
给出\(a_i\)表示第\(i\)天需要\(a_i\),一开始为\(0\)
同时给出\(c_i\)表示购买\(i\)需要\(c_i\)的花费。
现在一天最多拥有物品\(k\)个,如果目前有\(k\)个了,要加入一个,则需推掉一个,下次则需重新购买。
问满足所有的需求的最小花费为多少。

思路:

  • 显然,第\(i\)天必须要有物品\(a_i\)
  • 直接考虑不好考虑,我们可以先让每天都购买\(a_i\),满足硬性条件后,再在适当时候补偿以使答案更优。
  • 显然购买\(a_i\)之后要么卖掉,要么留到下一次用。
  • 那么我们将一个点拆为:\(i,i'\),然后连接\(S->i\),流量为\(1\),费用为\(c[i]\);连接\(i->i'\),流量为\(1\),费用为\(0\);连接\(i'->T\),流量为\(1\),费用为\(0\)。表示每天都购买,并且直接卖掉。
  • 之后连接\(i->i+1\),流量为\(k-1\),费用为\(0\),表示这本书留到后面。
  • 显然如果\(a_i=a_j\)且在\(i\)这个位置留到\(j\)的话,那么在流网络中一定能够留到\(j-1\)这个位置,那么我们连边\(j-1->i'\),流量为\(1\),费用为\(-c[i]\),用来弥补费用。

代码如下:

/*
 * Author:  heyuhhh
 * Created Time:  2019/10/29 21:52:13
 */
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 505, M = 2005;

struct E {
    int from, to, cp, v;
    E() {}
    E(int f, int t, int cp, int v) : from(f), to(t), cp(cp), v(v) {}
};

struct MCMF {
    int n, m, s, t;
    vector<E> edges;
    vector<int> G[N];
    bool inq[N];
    int d[N], p[N], a[M];

    void init(int _n, int _s, int _t) {
        n = _n; s = _s; t = _t;
        for(int i = 0; i <= n; i++) G[i].clear();
        edges.clear(); m = 0;
    }

    void addedge(int from, int to, int cap, int cost) {
        edges.emplace_back(from, to, cap, cost);
        edges.emplace_back(to, from, 0, -cost);
        G[from].push_back(m++);
        G[to].push_back(m++);
    }

    bool BellmanFord(int &flow, int &cost) {
        for(int i = 0; i <= n; i++) d[i] = INF;
        memset(inq, 0, sizeof inq);
        d[s] = 0, a[s] = INF, inq[s] = true;
        queue<int> Q; Q.push(s);
        while (!Q.empty()) {
            int u = Q.front(); Q.pop();
            inq[u] = false;
            for (int& idx: G[u]) {
                E &e = edges[idx];
                if (e.cp && d[e.to] > d[u] + e.v) {
                    d[e.to] = d[u] + e.v;
                    p[e.to] = idx;
                    a[e.to] = min(a[u], e.cp);
                    if (!inq[e.to]) {
                        Q.push(e.to);
                        inq[e.to] = true;
                    }
                }
            }
        }
        if (d[t] == INF) return false;
        flow += a[t];
        cost += a[t] * d[t];
        int u = t;
        while (u != s) {
            edges[p[u]].cp -= a[t];
            edges[p[u] ^ 1].cp += a[t];
            u = edges[p[u]].from;
        }
        return true;
    }

    int go() {
        int flow = 0, cost = 0;
        while (BellmanFord(flow, cost));
        return cost;
    }
} MM;

int n, k;
int a[N], c[N];

void run(){
    for(int i = 1; i <= n; i++) cin >> a[i];
    for(int i = 1; i <= n; i++) cin >> c[i];
    int S = 0, T = 2 * n + 1;
    MM.init(T + 1, S, T);
    for(int i = 1; i <= n; i++) MM.addedge(S, i, 1, c[a[i]]);
    for(int i = 1; i <= n; i++) {
        MM.addedge(i, i + n, 1, 0);
        if(i < n) MM.addedge(i, i + 1, k - 1, 0);
        MM.addedge(i + n, T, 1, 0);
    }
    for(int i = 1; i <= n; i++) {
        for(int j = i + 1; j <= n; j++) {
            if(a[i] == a[j]) {
                MM.addedge(j - 1, i + n, 1, -c[a[i]]);
            }
        }
    }
    int ans = MM.go();
    cout << ans << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n >> k) run();
    return 0;
}

【CF802C】Heidi and Library(网络流)

标签:cos   queue   现在   main   make   add   题意   syn   sync   

原文地址:https://www.cnblogs.com/heyuhhh/p/11762083.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!