/* I will wait for you */
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <string>
#define make make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int maxn = 1000010;
const int maxm = 1010;
const int maxs = 26;
const int inf = 0x3f3f3f3f;
const int P = 1000000007;
const double error = 1e-9;
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9')
f = (ch == '-' ? -1 : 1), ch = getchar();
while (ch >= '0' && ch <= '9')
x = x * 10 + ch - '0', ch = getchar();
return x * f;
}
struct edge
{
int v, a;
ll w;
int next;
} e[maxn];
int s, t, u, n, m, cnt, head[maxn],
vi[maxn], vis[maxn], q[maxn];
ll ans, dis[maxn];
void insert(int u, int v, int a, ll w)
{
e[cnt] = (edge) {v, a, w, head[u]};
head[u] = cnt++;
e[cnt] = (edge) {u, 0, -w, head[v]};
head[v] = cnt++;
}
bool spfa()
{
for (int i = 1; i <= t; i++)
dis[i] = inf, vis[i] = 0;
int he = 0, ta = 1;
q[0] = t, dis[t] = 0;
while (he != ta) {
int u = q[he++];
vis[u] = 0;
he %= 1000000;
for (int i = head[u]; i != -1;
i =e[i].next) {
int v = e[i].v;
if (e[i ^ 1].a &&
dis[v] > dis[u] - e[i].w) {
dis[v] = dis[u] - e[i].w;
if (!vis[v]) {
vis[v] = 1;
q[ta++] = v;
ta %= 1000000;
}
}
}
}
return dis[s] < inf;
}
int dfs(int u, int a)
{
vis[u] = 1;
if (u == t) return a;
int f, flow = 0;
for (int i = head[u]; a && i != -1; i = e[i].next) {
int v = e[i]. v;
if (!vis[v] && e[i].a &&
dis[u] == dis[v] + e[i].w) {
f = dfs(v, min(a, e[i].a));
e[i].a -= f, e[i^1].a += f;
a -= f, flow += f;
ans += f * e[i].w;
}
}
return flow;
}
void dinic()
{
while (spfa()) {
vis[t] = 1;
while (vis[t]) {
for (int i = 1; i <= t; i++)
vis[i] = 0;
dfs(s, inf);
}
}
}
int main()
{
n = read(), m = read();
memset(head, -1, sizeof head);
for (int i = 1; i <= n; i++) {
scanf("%d", &vi[i]);
insert(i, n + i, vi[i], -inf);
}
for (int i = 1, v; i <= n; i++)
for (int j = i + 1; j <= n; j++) {
scanf("%d", &v);
if (v != -1)
insert(n + i, j, inf, v);
}
s = 2 * n + 1, u = 2 * n + 2, t = 2 * n + 3;
for (int i = 1; i <= n; i++) {
insert(u, i, inf, 0);
insert(n + i, t, inf, 0);
}
insert(s, u, m, 0);
dinic();
for (int i = 1; i <= n; i++)
ans += (ll) inf * vi[i];
printf("%lld\n", ans);
return 0;
}
BZOJ2055【上下界费用流】
最新推荐文章于 2021-08-02 20:58:50 发布