• loj6045 「雅礼集训 2017 Day8」价


    传送门:https://loj.ac/problem/6045

    【题解】

    由于存在完美匹配,所以选择k个药就要选择>=k个药材,我们要求的是选择k个药正好选择k个药材。

    那么定义选一种减肥药的代价为-pi+INF,选一种药材的代价为INF,这样最小割肯定是恰好选k个

    那么 最后答案就是最小割 - Σ(-pi+INF) 【由于减肥药是负的所以要反过来。。。】

    中间连的边要设成比inf大的。。

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int N = 600 + 10, M = 5e5 + 10;
    const int mod = 1e9+7, inf = 5e6, INF = 1e9;
    
    # define RG register
    # define ST static
    
    int n, m[N], a[N][N], p[N], S, T;
    int head[N], nxt[M], to[M], flow[M], tot=1;
    
    inline void add(int u, int v, int fl) {
        ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v; flow[tot] = fl;
    }
    inline void adde(int u, int v, int fl) {
        add(u, v, fl), add(v, u, 0);
    }
    
    namespace MF {
        struct queue {
            int head, tail, q[M];
            inline void set() {
                head = 1, tail = 0;
            }
            inline void push(int x) {
                q[++tail] = x;
            }
            inline void pop() {
                ++head;
            }
            inline int front() {
                return q[head];
            }
            inline bool empty() {
                return head > tail;
            }
        }q;
        
        int c[N], cur[N]; 
        inline bool bfs() {
            for (int i=1; i<=n+n+2; ++i) c[i] = -1;
            q.set(); q.push(S); c[S] = 1;
            while(!q.empty()) {
                int top = q.front(); q.pop();
                for (int i=head[top]; i; i=nxt[i]) {
                    if(c[to[i]] != -1 || flow[i] == 0) continue;
                    c[to[i]] = c[top] + 1;
                    q.push(to[i]);
                    if(to[i] == T) return 1;
                }
            }
            return 0;
        }
        
        inline int dfs(int x, int low) {
            if(x == T) return low;
            int r = low, fl;
            for (int i=cur[x]; i; i=nxt[i]) {
                if(c[to[i]] != c[x]+1 || flow[i] == 0) continue;
                fl = dfs(to[i], min(r, flow[i]));
                flow[i] -= fl; flow[i^1] += fl; r -= fl;
                if(flow[i] > 0) cur[x] = i; 
                if(!r) return low;
            }
            if(r == low) c[x] = -1; 
            return low-r;
        }
        
        inline int main() {
            int ans = 0; 
            while(bfs()) {
                for (int i=1; i<=n+n+2; ++i) cur[i] = head[i];
                ans += dfs(S, INF); 
            }
            return ans;
        }
    }
    
    int ans = 0;
    int main() {
        freopen("z.in", "r", stdin);
        freopen("z.out", "w", stdout); 
        cin >> n;
        for (int i=1; i<=n; ++i) {
            cin >> m[i];
            for (int j=1; j<=m[i]; ++j) {
                scanf("%d", &a[i][j]);
                adde(i, a[i][j] + n, INF);
            }
        }
        for (int i=1; i<=n; ++i) scanf("%d", p+i);
        S = n+n+1, T = n+n+2;
        for (int i=1; i<=n; ++i) adde(i+n, T, inf);
        for (int i=1; i<=n; ++i) adde(S, i, inf-p[i]), ans += inf-p[i];
        ans = MF::main() - ans;
        cout << ans << endl;
        return 0;
    }
    /*
    3 
    2 1 2 
    2 1 2 
    1 3 
    -10 20 -3 
    */
    View Code
  • 相关阅读:
    策略思维模式
    初学者之心
    《计算机思维》笔记
    通才论
    Shell 脚本中 set ex 命令的作用
    Python—requests模块详解
    SharePoint CSOM 迁移列表项权限
    实践剖析.NET Core如何支持Cookie和JWT混合认证、授权
    面试突击13:方法优先调用可选参数还是固定参数?
    如何构建一个疾病的动物模型? | animal model of disease
  • 原文地址:https://www.cnblogs.com/galaxies/p/loj6045.html
Copyright © 2020-2023  润新知