• 2018 Multi-University Training Contest 10


    最大费用最大流

    需要开一个源点,次源点,汇点,然后把电影当成点并拆开。

    源点到次源点连一条容量k费用0的边,次源点到每个电影拆开的点的一边都连一条容量1费用0的边,电影拆开的点两边连一条容量1费用为w的
    边,然后如果时间允许就在电影拆开的点的出点和另一个电影的入点连一条容量1费用-W的边,最后每个电影的出点和汇点连容量1费用0的边。

    跑最大费用最大流。。

    #include <bits/stdc++.h>
    #define INF 0x3f3f3f3f
    #define full(a, b) memset(a, b, sizeof a)
    #define FAST_IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
    using namespace std;
    typedef long long ll;
    inline int lowbit(int x){ return x & (-x); }
    inline int read(){
        int ret = 0, w = 0; char ch = 0;
        while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
        while(isdigit(ch)) ret = (ret << 3) + (ret << 1) + (ch ^ 48), ch = getchar();
        return w ? -ret : ret;
    }
    inline int gcd(int a, int b){ return b ? gcd(b, a % b) : a; }
    inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
    template <typename T>
    inline T max(T x, T y, T z){ return max(max(x, y), z); }
    template <typename T>
    inline T min(T x, T y, T z){ return min(min(x, y), z); }
    template <typename A, typename B, typename C>
    inline A fpow(A x, B p, C lyd){
        A ans = 1;
        for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
        return ans;
    }
    const int N = 5000;
    int _, n, m, k, w, cnt, s, t, head[N<<1], d[N<<1], incf[N<<1], pre[N<<1];
    bool inq[N<<1];
    struct Edge { int v, next, f, cost; } edge[N<<2];
    struct Videos{ int l, r, w, op; } vi[N];
    void addEdge(int a, int b, int c, int d){
        edge[cnt].v = b, edge[cnt].f = c, edge[cnt].cost = d, edge[cnt].next = head[a], head[a] = cnt ++;
        edge[cnt].v = a, edge[cnt].f = 0, edge[cnt].cost = -d, edge[cnt].next = head[b], head[b] = cnt ++;
    }
    
    void build(){
        cnt = 0;
        full(head, -1), full(pre, -1), full(incf, INF);
    }
    
    bool spfa(){
        queue<int> q;
        full(d, 0xcf), full(inq, false);
        inq[s] = true, d[s] = 0, incf[s] = INF;
        q.push(s);
        while(!q.empty()){
            int cur = q.front(); q.pop(); inq[cur] = false;
            for(int i = head[cur]; i != -1; i = edge[i].next){
                int u = edge[i].v;
                if(edge[i].f > 0 && d[u] < d[cur] + edge[i].cost){
                    d[u] = d[cur] + edge[i].cost;
                    incf[u] = min(incf[cur], edge[i].f);
                    pre[u] = i;
                    if(!inq[u]) inq[u] = true, q.push(u);
                }
            }
        }
        return d[t] != 0xcfcfcfcf;
    }
    
    int mcmf(){
        int ret = 0;
        while(spfa()){
            int x = t;
            while(x != s){
                int i = pre[x];
                edge[i].f -= incf[t], edge[i^1].f += incf[t];
                x = edge[i^1].v;
            }
            ret += d[t] * incf[t];
        }
        return ret;
    }
    
    int main(){
    
        for(_ = read(); _; _ --){
            build();
            n = read(), m = read(), k = read(), w = read();
            for(int i = 1; i <= m; i ++){
                vi[i].l = read(), vi[i].r = read(), vi[i].w = read(), vi[i].op = read();
            }
            s = 2 * m + 1, t = 2 * m + 3;
            addEdge(s, s + 1, k, 0);
            for(int i = 1; i <= m; i ++){
                addEdge(s + 1, i, 1, 0), addEdge(i, i + m, 1, vi[i].w);
            }
            for(int i = 1; i <= m; i ++){
                for(int j = 1; j <= m; j ++){
                    if(vi[i].r <= vi[j].l)
                        addEdge(i + m, j, 1, vi[i].op == vi[j].op ? -w : 0);
                }
            }
            for(int i = 1; i <= m; i ++) addEdge(i + m, t, 1, 0);
            printf("%d
    ", mcmf());
        }
        return 0;
    }
    
  • 相关阅读:
    python os模块
    python time、datetime模块
    python 导入模块、包
    python json、pickle
    python 装饰器
    python 生成器、迭代器
    python 内置函数
    python 函数的参数
    python 编码解码
    python 文件读写、shutil模块
  • 原文地址:https://www.cnblogs.com/onionQAQ/p/11174881.html
Copyright © 2020-2023  润新知