• 【题解】JSOI2009球队收益 / 球队预算


      为什么大家都不写把输的场次增加的呢?我一定要让大家知道,这并没有什么关系~所以 (C[i] <= D[i]) 的条件就是来卖萌哒??

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 1000000
    #define INF 99999999
    int n, m, S, T, rec[maxn], flow[maxn], a[maxn], b[maxn];
    int ans, tot, c[maxn], d[maxn], dis[maxn], num[maxn];
    bool vis[maxn];
    
    int read() {
        int x = 0, k = 1;
        char c; c = getchar();
        while(c < '0' || c > '9') { if(c == '-') k = -1; c = getchar(); }
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * k;
    }
    
    struct edge {
        int cnp, to[maxn], last[maxn], head[maxn], f[maxn], co[maxn];
        edge() { cnp = 2; }
        void add(int u, int v, int fl, int w) {
            to[cnp] = v, f[cnp] = fl, co[cnp] = w, last[cnp] = head[u], head[u] = cnp ++;
            to[cnp] = u, f[cnp] = 0, co[cnp] = -w, last[cnp] = head[v], head[v] = cnp ++;
        }
    }E1;
    
    struct node {
        int x, y;
    }P[maxn];
    
    int multi(int x) { return x * x; }
    void Build() {
        S = 0, T = 3 * m + 3;
        for(int i = 1; i <= n; i ++) {
            int A = a[i] + num[i], B = b[i];
            if(num[i]) rec[i] = tot + 1;
            for(int j = 1; j <= num[i]; j ++) {
                ++ tot; 
                E1.add(tot, T, 1, 2 * B * d[i] - 2 * A * c[i] + c[i] + d[i]);
                if(j != num[i]) E1.add(tot, tot + 1, INF, 0);
                A --, B ++;
            }
        }
        for(int i = 1; i <= m; i ++) {
            E1.add(S, ++ tot, 1, 0);
            E1.add(tot, rec[P[i].x], 1, 0);
            E1.add(tot, rec[P[i].y], 1, 0);
        }
    }
    
    bool SPFA() {
        queue <int> q;
        for(int i = 0; i <= T; i ++) dis[i] = INF, vis[i] = 0;
        q.push(S); dis[S] = 0; flow[S] = INF;
        while(!q.empty()) {
            int u = q.front(); q.pop(); vis[u] = 0;
            for(int i = E1.head[u]; i; i = E1.last[i]) {
                int v = E1.to[i];
                if(!E1.f[i]) continue;
                if(dis[v] > dis[u] + E1.co[i]) {
                    dis[v] = dis[u] + E1.co[i]; 
                    rec[v] = i, flow[v] = min(flow[u], E1.f[i]);
                    if(!vis[v]) q.push(v), vis[v] = 1;
                }
            }
        }
        if(dis[T] != INF) return 1;
        return 0;
    }
    
    int Max_Flow() {
        int ans = 0, cost = 0;
        while(SPFA()) {
            int u = T;
            while(u != S) {
                int t = rec[u]; 
                E1.f[t] -= flow[T], E1.f[t ^ 1] += flow[T];
                u = E1.to[t ^ 1];
            }
            ans += flow[T], cost += dis[T] * flow[T];
        }
        return cost;
    }
    
    int main() {
        n = read(), m = read();
        for(int i = 1; i <= n; i ++) {
            a[i] = read(), b[i] = read(), c[i] = read(), d[i] = read();
        }
        for(int i = 1; i <= m; i ++) {
            int x = read(), y = read();
            num[x] ++, num[y] ++; P[i].x = x, P[i].y = y;
        }
        for(int i = 1; i <= n; i ++)
            ans += c[i] * multi(a[i] + num[i]) + d[i] * multi(b[i]);
        Build();
        printf("%d
    ", ans + Max_Flow());
        return 0;
    }
  • 相关阅读:
    say goodbye to Heroku All In One
    Next.js Conf Ticket All In One
    如何在 macOS 上使用 iMovie 进行视频剪辑教程 All In One
    河流水质等级 All In One
    Leetcdoe 2037. 使每位学生都有座位的最少移动次数(可以,一次过)
    Leetcode 2190. 数组中紧跟 key 之后出现最频繁的数字(可以,一次过)
    Leetcode 2164. 对奇偶下标分别排序(可以,一次过)
    C++ std::function的用法
    利用torch.nn实现前馈神经网络解决 回归 任务
    pytorch 中 torch.nn.Linear() 详解
  • 原文地址:https://www.cnblogs.com/twilight-sx/p/10380993.html
Copyright © 2020-2023  润新知