可行流应该是跑完 Dinic 之后的从 T 到 S 的反向边的剩余容量,而不是这次跑 Dinic 跑出来的流。但是,就算按照这种错误方法写,仍然可以通过此题。
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <cstring>
#include <queue>
#define int long long
using namespace std;
const int N = 370, M = 1e3 + 10, C = 3e2 + 10, INF = 0x3f3f3f3f;
int n, m, s, t, ss, tt;
struct node {
int from, to, next, siz;
node() {}
node(int _from, int _to, int _next, int _siz) {
from = _from, to = _to, next = _next, siz = _siz;
}
}ed[(N * C + M) << 1];
int pre[N + M], rad[N + M];
void add(int x, int y, int siz) {
ed[++pre[0]] = node(x, y, pre[x], siz);
pre[x] = pre[0];
ed[++pre[0]] = node(y, x, pre[y], 0);
pre[y] = pre[0];
}
int tflow[N + M];
void clear() {
memset(tflow, 0, sizeof(tflow));
memset(pre, 0, sizeof(pre));
pre[0] = 1;
}
int dep[N + M];
queue<int> q;
bool bfs() {
memset(dep, 0, sizeof(dep));
dep[s] = 1;
q.push(s);
while (!q.empty()) {
int now = q.front();
q.pop();
rad[now] = pre[now];
for (int i = pre[now]; i != 0; i = ed[i].next) {
if (dep[ed[i].to] != 0 || ed[i].siz == 0) continue;
dep[ed[i].to] = dep[now] + 1;
q.push(ed[i].to);
}
}
return dep[t] != 0;
}
int dfs(int now, int sum) {
if (now == t) return sum;
int val = sum;
for (int i = rad[now]; i != 0; i = ed[i].next) {
rad[now] = i;
if (dep[ed[i].to] != dep[now] + 1 || ed[i].siz == 0) continue;
int tmp = dfs(ed[i].to, min(val, ed[i].siz));
ed[i].siz -= tmp;
ed[i ^ 1].siz += tmp;
val -= tmp;
if (val == 0) break;
}
return sum - val;
}
int dinic() {
int res = 0;
while (bfs()) {
res += dfs(s, INF);
}
return res;
}
signed main() {
while (scanf("%lld%lld", &n, &m) != EOF) {
clear();
s = n + m + 1, t = n + m + 2, ss = n + m + 3, tt = n + m + 4;
for (int i = 1; i <= m; i++) {
int g;
scanf("%lld", &g);
add(n + i, t, INF);
tflow[n + i] -= g;
tflow[t] += g;
}
for (int i = 1; i <= n; i++) {
int c, d;
scanf("%lld%lld", &c, &d);
add(s, i, d);
for (int j = 1; j <= c; j++) {
int _t, l, r;
scanf("%lld%lld%lld", &_t, &l, &r);
_t++;
add(i, n + _t, r - l);
tflow[i] -= l;
tflow[n + _t] += l;
}
}
int mxflow = 0;
for (int i = 1; i <= t; i++)
if (tflow[i] < 0) add(i, tt, -tflow[i]);
else if (tflow[i] > 0) add(ss, i, tflow[i]), mxflow += tflow[i];
add(t, s, INF);
s = ss, t = tt;
if (dinic() != mxflow) {
printf("-1\n\n");
continue;
}
ed[pre[0]].siz = ed[pre[0] ^ 1].siz = 0;
s = n + m + 1, t = n + m + 2;
printf("%d\n\n", mxflow/*错误*/ + dinic());
}
}
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <cstring>
#include <queue>
#define int long long
using namespace std;
const int N = 370, M = 1e3 + 10, C = 3e2 + 10, INF = 0x3f3f3f3f;
int n, m, s, t, ss, tt;
struct node {
int from, to, next, siz;
node() {}
node(int _from, int _to, int _next, int _siz) {
from = _from, to = _to, next = _next, siz = _siz;
}
}ed[(N * C + M) << 1];
int pre[N + M], rad[N + M];
void add(int x, int y, int siz) {
ed[++pre[0]] = node(x, y, pre[x], siz);
pre[x] = pre[0];
ed[++pre[0]] = node(y, x, pre[y], 0);
pre[y] = pre[0];
}
int tflow[N + M];
void clear() {
memset(tflow, 0, sizeof(tflow));
memset(pre, 0, sizeof(pre));
pre[0] = 1;
}
int dep[N + M];
queue<int> q;
bool bfs() {
memset(dep, 0, sizeof(dep));
dep[s] = 1;
q.push(s);
while (!q.empty()) {
int now = q.front();
q.pop();
rad[now] = pre[now];
for (int i = pre[now]; i != 0; i = ed[i].next) {
if (dep[ed[i].to] != 0 || ed[i].siz == 0) continue;
dep[ed[i].to] = dep[now] + 1;
q.push(ed[i].to);
}
}
return dep[t] != 0;
}
int dfs(int now, int sum) {
if (now == t) return sum;
int val = sum;
for (int i = rad[now]; i != 0; i = ed[i].next) {
rad[now] = i;
if (dep[ed[i].to] != dep[now] + 1 || ed[i].siz == 0) continue;
int tmp = dfs(ed[i].to, min(val, ed[i].siz));
ed[i].siz -= tmp;
ed[i ^ 1].siz += tmp;
val -= tmp;
if (val == 0) break;
}
return sum - val;
}
int dinic() {
int res = 0;
while (bfs()) {
res += dfs(s, INF);
}
return res;
}
signed main() {
while (scanf("%lld%lld", &n, &m) != EOF) {
clear();
s = n + m + 1, t = n + m + 2, ss = n + m + 3, tt = n + m + 4;
for (int i = 1; i <= m; i++) {
int g;
scanf("%lld", &g);
add(n + i, t, INF);
tflow[n + i] -= g;
tflow[t] += g;
}
for (int i = 1; i <= n; i++) {
int c, d;
scanf("%lld%lld", &c, &d);
add(s, i, d);
for (int j = 1; j <= c; j++) {
int _t, l, r;
scanf("%lld%lld%lld", &_t, &l, &r);
_t++;
add(i, n + _t, r - l);
tflow[i] -= l;
tflow[n + _t] += l;
}
}
int mxflow = 0;
for (int i = 1; i <= t; i++)
if (tflow[i] < 0) add(i, tt, -tflow[i]);
else if (tflow[i] > 0) add(ss, i, tflow[i]), mxflow += tflow[i];
add(t, s, INF);
s = ss, t = tt;
if (dinic() != mxflow) {
printf("-1\n\n");
continue;
}
int tmp = ed[pre[0]].siz;/*正确*/
ed[pre[0]].siz = ed[pre[0] ^ 1].siz = 0;
s = n + m + 1, t = n + m + 2;
printf("%d\n\n", tmp + dinic());
}
}