UVALive 7152 Catering (有上下界的)费用流

有n+1个点的图,点编号是从0到n,有k个机器在0号点。一个机器可以从编号小的可以往编号大的走,反之不行。机器可以经过很多点。若有一个点被某个机器经过,那么这个点就被处理。对于每个点都可以通往编号比它大的点,都需要一定的花费。求让所有点都被处理的最小花费。

输入格式:输入文件包含多组数据,对于每组数据,先是n,k,接下来n行每行描述一个点的情况,先是0号点到1、2、….、n号点的花费,然后是1号点到2、3、…、n号点的花费,直到n-1号点的情况。输出最小花费。

构图跑费用流啦
肯定要拆点啦。
对每个点i,建立i->i’,流量[1,1],费用0;建立i’->t,流量inf,费用0。
对每条边,建立i’->j,流量inf,费用c。
对0,建立s->0,流量[k,k],费用0。
有上下界费用流即可。。。。。。。

似乎是每个点只能走一次。。。。
因为i->i’的流量改成[1,inf]就挂了。。

虽然构图和标程一样,但是出题人却说并不是上下界的,求教?

对于下界的事情,不需要有上下界费用流的问题。
我们可以考虑将费用设置为-inf,这样i->i’就肯定会通过的啦。
最后把inf加回来就好了。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define FOR(i,j,k) for(i=j;i<=k;++i)
using namespace std;
const int N = 210, M = 1000000, inf = 0x3f3f3f3f;

int h[N], p[M], v[M], w[M], c[M], vis[N], d[N], pre[N], q[M], cnt;
int s, t, ans;

void init(int _s, int _t) {
    s = _s; t = _t; cnt = 0;
    memset(h, -1, sizeof h);
}

void add(int i, int j, int k, int l) {
    p[cnt] = h[i]; v[cnt] = j; w[cnt] = k; c[cnt] = l; h[i] = cnt ++;
    p[cnt] = h[j]; v[cnt] = i; w[cnt] = 0; c[cnt] = -l; h[j] = cnt ++;
}

bool spfa() {
    memset(d, 0x3f, sizeof d);
    memset(vis, 0, sizeof vis);
    int f = 1, r = 1, u, i;
    q[r++] = s; d[s] = 0; pre[s] = pre[t] = -1; vis[s] = 1;
    while (f < r) {
        u = q[f++];
        for (i = h[u]; i != -1; i = p[i])
            if (w[i] > 0 && d[v[i]] > d[u] + c[i]) {
                d[v[i]] = d[u] + c[i];
                pre[v[i]] = i ^ 1;
                if (!vis[v[i]]) {
                    q[r++] = v[i];
                    vis[v[i]] = 1;
                }
            }
        vis[u] = 0;
    }
    return d[t] != inf;
}

void end() {
    int u, sum = inf;
    for (u = pre[t]; u != -1; u = pre[v[u]])
        sum = min(sum, w[u ^ 1]);
    for (u = pre[t]; u != -1; u = pre[v[u]])
        w[u] += sum, w[u ^ 1] -= sum, ans += sum * c[u ^ 1];
}

int solve() {
    ans = 0;
    while (spfa()) end();
    return ans;
}

int main() {
    int n, k, i, j, x;
    while (scanf("%d%d", &n, &k) != EOF) {
        init(2 * n + 2, 2 * n + 3);
        FOR(i,0,n) FOR(j,i+1,n) scanf("%d", &x), add(i, j + n + 1, inf, x);
        add(s, 0, k, 0);
        FOR(i,1,n) add(s, i, 1, 0), add(i + n + 1, t, 1, 0);
        printf("%d\n", solve());
    }
    return 0;
}

Catering

Paul owns a catering company and business is booming. The company has k catering teams, each in charge of one set of catering equipment. Every week, the company accepts n catering requests for various events. For every request, they send a catering team with their equipment to the event location. The team delivers the food, sets up the equipment, and instructs the host on how to use the equipment and serve the food. After the event, the host is responsible for returning the equipment back to Paul’s company. Unfortunately, in some weeks the number of catering teams is less than the number of requests, so some teams may have to be used for more than one event. In these cases, the company cannot wait for the host to return the equipment and must keep the team on-site to move the equipment to another location. The company has an accurate estimate of the cost to move a set of equipment from any location to any other location. Given these costs, Paul wants to prepare an Advance Catering Map to service the requests while minimizing the total moving cost of equipment (including the cost of the first move), even if that means not using all the available teams. Paul needs your help to write a program to accomplish this task. The requests are sorted in ascending order of their event times and they are chosen in such a way that for any i < j, there is enough time to transport the equipment used in the i-th request to the location of the j-th request.

Input

The input file contains several test cases, each of them as described below. The first line of input contains two integers n (1 ≤ n ≤ 100) and k (1 ≤ k ≤ 100) which are the number of requests and the number of catering teams, respectively. Following that are n lines, where the i-th line contains n − i + 1 integers between 0 and 1 000 000 inclusive. The j-th number in the i-th line is the cost of moving a set of equipment from location i to location i + j. The company is at location 1 and the n requests are at locations 2 to n + 1.

Output

For each test case, display the minimum moving cost to service all requests. (This amount does not include the cost of moving the equipment back to the catering company.)

Sample Input

3 2
40 30 40
50 10
50
3 2
10 10 10
20 21
21

Sample Output

80
40

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值