zoukankan      html  css  js  c++  java
  • XVI Open Cup named after E.V. Pankratiev. GP of Ekaterinburg--I.Iron man

    n个服务器,k类任务,每个服务器完成一个任务都有特定的花费$cost_{i,j}$,但是你设置好某台机器去完成某项任务时他只能去完成这类任务,除非你可以花费$C$去更改配置。第$i$天要求去完成$q_{i,j}$个j类任务,问如何让总代价最小

    用费用流去优化dp

    #include <bits/stdc++.h>
    using namespace std;
    #define rep(i, j, k) for (int i = int(j); i <= int(k); ++ i)
    #define dwn(i, j, k) for (int i = int(j); i >= int(k); -- i)
    typedef long long LL;
    typedef pair<int, int> P;
    typedef vector<int> VI;
    typedef vector<P> VII;
    const int inf = 1e9;
    const int N  = 50;
    int cost[20][20], a[110][20], dp[110];
    struct Edge {
        int from, to, cap, flow, cost;
    };
    struct MCMF {
        int n;
        vector<Edge> edges;
        vector<int> g[N];
        int inq[N], d[N], p[N], a[N];
        void add(int u, int v, int cap, int cost) {
            edges.push_back((Edge){u, v, cap, 0, cost});
            edges.push_back((Edge){v, u, 0, 0, -cost});
            int m = edges.size();
            g[u].push_back(m - 2);
            g[v].push_back(m - 1);
        }
        bool spfa(int s, int t, int &flow, int &cost){
            rep(i, 0, n) d[i] = inf;
            memset(inq, 0, sizeof(inq));
            d[s] = 0; inq[s] = 1; p[s] = 0; a[s] = inf;
            queue<int> Q;
            Q.push(s);
            while (!Q.empty()) {
                int u = Q.front(); Q.pop();
                inq[u] = 0;
                for (int i = 0; i < g[u].size(); ++ i) {
                    Edge &e = edges[g[u][i]];
                    if (e.cap > e.flow && d[e.to] > d[u] + e.cost) {
                        d[e.to] = d[u] + e.cost;
                        p[e.to] = g[u][i];
                        a[e.to] = min(a[u], e.cap - e.flow);
                        if (!inq[e.to]) {
                            Q.push(e.to);
                            inq[e.to] = 1;
                        }
                    }
                }
            }
            if (d[t] == inf) return 0;
            flow += a[t];
            cost += d[t] * a[t];
            int u = t;
            while (u != s) {
                edges[p[u]].flow += a[t];
                edges[p[u] ^ 1].flow -= a[t];
                u = edges[p[u]].from;
            }
            return 1;
        }
        int minCost(int s, int t) {
            int flow = 0, cost = 0;
            while (spfa(s, t, flow, cost)) continue; return cost;
        }
    }solver;
    
    int main() {
        int n, k, c, m;
        scanf("%d%d%d", &n, &k, &c);   // n个服务器,k类任务
        scanf("%d", &m);
        memset(cost, -1, sizeof(cost));
        rep(i, 1, m) {
            int s, t, w;
            scanf("%d%d%d", &s, &t, &w);
            cost[s][t] = w; // s 完成第t个任务的代价为w
        }
        int q;
        scanf("%d", &q);
        rep(i, 1, q) {
            rep(j, 1, k) scanf("%d", &a[i][j]); // 第i天需要j服务器的数量
            rep(j, 1, k) a[i][j] = a[i - 1][j] + a[i][j];
        }
        auto calcCost = [&](int l, int r) -> int{
            static int sum[20];
            rep(i, 1, k) sum[i] = a[r][i] - a[l - 1][i];    
            // rep(i, 1, k) cout << sum[i] << ' '; cout << '
    ';
            rep(i, 0, solver.n) solver.g[i].clear();
            solver.edges.clear();
            // n 个服务器, k 类任务
            int src = n + k + 1, dest = n + k + 2;
            solver.n = dest;
            rep(i, 1, n) solver.add(src, i, 1, 0);
            rep(i, 1, n) rep(j, 1, k) 
                if (cost[i][j] >= 0 && sum[j]) solver.add(i, j + n, 1, cost[i][j] * sum[j]);
            // 必须要第i个服务器可以完成第j类任务
            rep(i, 1, k) solver.add(i + n, dest, sum[i] > 0, 0);
            return solver.minCost(src, dest);
        };
        dp[0] = 0;
        rep(i, 1, q) {
            dp[i] = inf;
            rep(j, 0, i - 1) dp[i] = min(dp[i], dp[j] + calcCost(j + 1, i) + c);
        }
        printf("%d
    ", dp[q]);
    }
    /*
    5 5 10
    12
    1 1 63
    2 1 37
    2 2 12
    3 2 98
    5 2 57
    2 3 74
    3 3 55
    4 3 32
    1 4 62
    3 4 18
    2 5 21
    4 5 42
    10
    97 20 29 95 46
    51 32 96 53 37
    60 85 50 23 94
    92 11 53 26 46
    66 64 18 0 58
    18 2 3 97 37
    17 11 73 7 93
    36 30 31 27 51
    22 35 31 77 1
    83 68 66 64 64
    */
  • 相关阅读:
    vue生命周期简介和钩子函数
    vue.js 笔记
    vue-cli安装以及搭建vue项目详细步骤
    nodejs 报错
    线程池 一 ThreadPoolExecutor
    JUC 一 线程池
    线程八锁
    JUC 一 ReentrantReadWriteLock
    JUC 一 ReentrantLock 可重入锁
    JUC 一 CountDownLatch(闭锁)
  • 原文地址:https://www.cnblogs.com/tempestT/p/10764883.html
Copyright © 2011-2022 走看看