题目地址:P2050 [NOI2012]美食节

先来讲一下P2053 [SCOI2007]修车(如果会做请跳过)

同一时刻有 \(N\) 位车主带着他们的爱车来到了汽车维修中心。维修中心共有 \(M\) 位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的。现在需要安排这 \(M\) 位技术人员所维修的车及顺序,使得顾客平均等待的时间最小。
说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。
\(2 \leq M \leq 9,1 \leq N \leq 60,1 \leq T \leq 1000\) 。

费用提前计算

注意到每位车主的等待时间除了跟自己的车所需的维修时间有关之外,还跟同一位技术人员之前维修所花的时间有关,这导致我们很难直观地建模。

但是仔细观察可以发现,一个人维修所花的时间,对同一位技术人员之后的维修造成的影响是已知且固定的。

那么,我们将费用提前计算,即,把第 \(i\) 位车主的车由第 \(j\) 位维修人员倒数第 \(k\) 个维修所花的时间(费用)当作 \(k \times t_{i,j}\) 。

从源点向每位车主连边,容量为 \(1\) ,费用为 \(0\) 。

每位维修人员拆成 \(n\) 个点,向汇点连边,容量为 \(1\) ,费用为 \(0\) 。

第 \(i\) 位车主向第 \(j\) 位维修人员拆成的第 \(k\) 个点连边,容量为 \(1\) ,费用为 \(k \times t_{i,j}\) 。

求最小费用最大流即可。

回到P2050 [NOI2012]美食节

此题为 P2053 [SCOI2007]修车 的数据加强版。
\(N \leq 40,M \leq 100\) 。

P2053 [SCOI2007]修车 的建图方式,但是硬求最小费用最大流只能拿到 \(60\) 分。

动态开点

起初每个厨师只拆成一个点,每次增广时,把当下的厨师拆出一个新点。

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 6, M = 4e7 + 6, inf = 0x3f3f3f3f;
int n, m, s, t, ans, d[N], pre[N], now[N], num, p[N];
int Head[N], Edge[M], Leng[M], Cost[M], Next[M], tot = 1;
bitset<N> v;
int a[46][106];

inline void add(int x, int y, int z, int w) {
    Edge[++tot] = y;
    Leng[tot] = z;
    Cost[tot] = w;
    Next[tot] = Head[x];
    Head[x] = tot;
}

inline bool spfa() {
    v.reset();
    memset(d, 0x3f, sizeof(d));
    queue<int> q;
    q.push(s);
    v[s] = 1;
    d[s] = 0;
    now[s] = inf;
    while (q.size()) {
        int x = q.front();
        q.pop();
        v[x] = 0;
        for (int i = Head[x]; i; i = Next[i]) {
            int y = Edge[i], z = Leng[i], w = Cost[i];
            if (!z || d[y] <= d[x] + w) continue;
            d[y] = d[x] + w;
            now[y] = min(now[x], z);
            pre[y] = i;
            if (!v[y]) {
                q.push(y);
                v[y] = 1;
            }
        }
    }
    return d[t] != inf;
}

inline void upd() {
    ans += d[t] * now[t];
    int x = t;
    while (x != s) {
        int i = pre[x];
        Leng[i] -= now[t];
        Leng[i^1] += now[t];
        x = Edge[i^1];
    }
    x = Edge[pre[t]^1];
    p[++num] = p[x];
    add(num, t, 1, 0);
    add(t, num, 0, 0);
    for (int i = Head[x]; i; i = Next[i]) {
        int y = Edge[i], w = Cost[i^1];
        if (y == t) continue;
        w += a[y][p[x]];
        add(y, num, 1, w);
        add(num, y, 0, -w);
    }
}

int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        int x;
        scanf("%d", &x);
        add(0, i, x, 0);
        add(i, 0, 0, 0);
    }
    num = t = n + m + 1;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) {
            int x;
            scanf("%d", &x);
            a[i][j] = x;
            add(i, n + j, 1, x);
            add(n + j, i, 0, -x);
        }
    for (int i = 1; i <= m; i++) {
        add(n + i, t, 1, 0);
        add(t, n + i, 0, 0);
        p[n+i] = i;
    }
    while (spfa()) upd();
    cout << ans << endl;
    return 0;
}

P2050 [NOI2012]美食节的更多相关文章

  1. P2050 [NOI2012]美食节(费用流)

    P2050 [NOI2012]美食节 P2053 [SCOI2007]修车的加强版 因为数据较大,一次性把所有边都加完会T 于是我们每次只连需要的边跑费用流 就是开始先连所有厨师做倒数第1道菜 跑费用 ...

  2. 洛谷P2050 [NOI2012]美食节

    动态加边网络流 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring ...

  3. P2050 [NOI2012]美食节 动态连边优化费用流

    题意 类似的一道排队等候,算最小总等待时间的题目. 思路 但是这道题的边数很多,直接跑会tle,可以动态加边,就是先连上倒数第一次操作的边,跑一遍费用流,然后对使用了倒数第一条边的点,连上相应的倒数第 ...

  4. P2050 [NOI2012]美食节 动态加边加点

    修车数据加强版 需要动态加边加点 #include<bits/stdc++.h> using namespace std; const int INF = 0x7f7f7f7f; , MA ...

  5. 洛谷$P2050\ [NOI2012]$美食节 网络流

    正解:网络流 解题报告: 传送门$QwQ$ 昂开始看到$jio$得,哇长得好像上一题嗷$QwQ$ 然后仔细康康数据范围,发现,哇好像要几万个点,,,显然就$GG$了 但感$jio$思路方向好对的亚子? ...

  6. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  7. BZOJ 2879: [Noi2012]美食节 最小费用流 动态添边

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 324  Solved: 179[Submit][Status] ...

  8. BZOJ 2879: [Noi2012]美食节( 费用流 + 动态加边 )

    倒着做菜..然后考虑为当前的人做菜对后面的人的影响就可以了..要动态加边 --------------------------------------------------------------- ...

  9. 【BZOJ2879】[Noi2012]美食节 动态加边网络流

    [BZOJ2879][Noi2012]美食节 Description CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他很快就尝遍了美食 ...

随机推荐

  1. linux下创建用户组与用户 只能访问指定目录的方法 以及FTP用户配置详解

    VSFTPD 安装: -- 查看是否已经安装 VSftpd: rpm -qa | grep vsftp yum install -y vsftpd groupadd ftpuser #创建ftpuse ...

  2. Shiro中session超时页面跳转的处理

    问题描述 shiro在管理session后,在session超时会进行跳转,这里有两种情况需要考虑,一种是ajax方式的请求超时,一种页面跳转请求的超时. 本文从这两个方面分别考虑并处理. ajax请 ...

  3. Hadoop记录-HDFS balancer配置

    HDFS balancer配置(可通过CM配置)dfs.datanode.balance.max.concurrent.moves 并行移动的block数量,默认5 dfs.datanode.bala ...

  4. Linux 内核源代码根目录

    1.    arch :与体系结构相关的文件 2.    block: 包含块存储设备IO调度算法的实现 3.    cryrto: 密码操作有关 4.    Documention: 内核中各个子系 ...

  5. 2018牛客网暑期ACM多校训练营(第二场)G Transform(二分)

    题意 在一个数轴上有n个集装箱,第 i 个集装箱的位置为x[i],且在集装箱内装有a[i]件货物,现在将这些集装箱内的货物进行移动(将一件货物从第 i 个集装箱移动到第 j 个集装箱的花费就为2*ab ...

  6. CSS脱离文档流&浮动

    什么是文档流? 将窗体从上至下分成一行一行,并在每行中按从左至右依次排放元素,称为文档流,也称为普通流.这个应该不难理解,HTML中全部元素都是盒模型,盒模型占用一定的空间,依次排放在HTML中,形成 ...

  7. 指定so动态链接库连接器

    在学习x86_64汇编时, 发现一旦使用glibc库函数, 如printf时, 一般是需要使用为ld传递命令行参数-lc来动态连接libc.so的, 但是, 生成的可执行文件却无法运行: 气煞我也! ...

  8. vue 中 使用百度编辑器 UEditor

    (单页应用,多编辑器也可行) 新建一个Ueditor.vue组件对象,该组件用来封装ueditor,用来进行复用. <template> <div> <!--下面通过传递 ...

  9. 一次enq: TX - index contention等待事件处理

    收到告警短信: BOMC一般告警,告警2次,最后告警时间:03-03 22:21,监控对象:/XX系统/数据库/ORACLE数据库/XXX.XX.XX.XX*XXXDB_LE_DBS/ORACLE实例 ...

  10. DevExpress Winform 常用控件

    Ø  前言 DevExpress 控件的功能比较强大,是全球知名控件开发公司,对于开发 B/S 或 C/S 都非常出色,可以实现很炫且功能强大的效果. DevExpress Winform 常用控件是 ...