注意事项
1.A可能为0
2.最后最大流总量需要开long long
#include <iostream>
#include <cstring>
using namespace std;
const int N = 2e5 + 10, M = (1e6 + 10 + 2 * N) * 2, INF = 1e9;
int h[N], e[M], ne[M], f[M], idx;
int q[N], cur[N], d[N];
int p[N];
int n, m;
int ss[8];
typedef long long LL;
LL sum;
int S, T;
void add(int a, int b, int c1, int c2)
{
e[idx] = b, ne[idx] = h[a], f[idx] = c1, h[a] = idx ++;
e[idx] = a, ne[idx] = h[b], f[idx] = c2, h[b] = idx ++;
}
bool bfs()
{
memset(d, -1, sizeof d);
int tt = 0, hh = 0;
cur[S] = h[S], d[S] = 0, q[0] = S;
while (hh <= tt)
{
int t = q[hh ++];
for (int i = h[t]; ~i; i = ne[i])
{
int ver = e[i];
if (f[i] > 0 && d[ver] == -1)
{
d[ver] = d[t] + 1;
cur[ver] = h[ver];
q[++ tt] = ver;
if (ver == T) return true;
}
}
}
return false;
}
int find(int u, int limit)
{
if (u == T) return limit;
int flow = 0;
for (int i = cur[u]; ~i && flow < limit; i = ne[i])
{
cur[u] = i;
int ver = e[i];
if (d[ver] == d[u] + 1 && f[i] > 0)
{
int t = find(ver, min(f[i], limit - flow));
if (!t) d[ver] = -1;
f[i] -= t, f[i ^ 1] += t, flow += t;
}
}
return flow;
}
LL dinic()
{
LL res = 0, flow;
while (bfs())
while (flow = find(S, INF)) res += flow;
return res;
}
int main()
{
memset(h, -1, sizeof h);
cin >> n >> m;
S = 2 * n + 1, T = 2 * n + 2;
for (int i = 0; i < 2 * n; i += 2)
{
int L, R, A, B, C;
scanf("%d%d%d%d%d", &L, &R, &A, &B, &C);
int max1 = - INF;
int max2 = - INF;
if (A)
{
ss[0] = - B / 2 / A, ss[1] = - B / 2 / A + 1, ss[2] = - B / 2 / A - 1, ss[3] = L + 1, ss[4] = R - 1;
ss[5] = L, ss[6] = R;
}
else
{
ss[0] = L + 1, ss[1] = L + 1, ss[2] = L + 1, ss[3] = L + 1, ss[4] = R - 1;
ss[5] = L, ss[6] = R;
}
max1 = max(max1, A * (L + 1) * (L + 1) + B * (L + 1) + C);
max1 = max(max1, A * (R - 1) * (R - 1) + B * (R - 1) + C);
for (int j = 0; j < 5; j ++)
if (L + 1 <= ss[j] && ss[j] <= R - 1)
max1 = max(max1, A * ss[j] * ss[j] + B * ss[j] + C);
max2 = max1;
for (int j = 5; j < 7; j ++)
max2 = max(max2, A * ss[j] * ss[j] + B * ss[j] + C);
p[i] = max1, p[i ^ 1] = max2 - max1;
add(i ^ 1, i, INF, 0);
}
while (m --)
{
int z, x, y;
scanf("%d%d%d", &z, &x, &y);
if (z == 1)
{
add(2 * (y - 1), 2 * (x - 1), INF, 0);
add(2 * (y - 1) + 1, 2 * (x - 1), INF, 0);
}
if (z == 2)
{
add(2 * (y - 1) + 1, 2 * (x - 1), INF, 0);
}
}
for (int i = 0; i < 2 * n; i ++)
{
if (p[i] < 0)
{
add(i, T, -p[i], 0);
}
else
{
add(S, i, p[i], 0);
sum += p[i];
}
}
cout << sum - dinic();
}