有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]就挂了。。
#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;
}
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.
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.
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.)
3 2
40 30 40
50 10
50
3 2
10 10 10
20 21
21
80
40