zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    解决 CAS + Spring Security整合 无法获取当前登录用户信息
    开发帮助网址收藏
    删除maven最近导入失败的文件
    二、maven的下载和安装配置
    一、maven的介绍
    数据结构学习笔记
    java网络URL请求编程入门
    Python学习(三)
    Python学习(二)
    EasyUI入门
  • 原文地址:https://www.cnblogs.com/onionQAQ/p/11174881.html
Copyright © 2011-2022 走看看