202006-5 乔乔和牛牛逛超市

注意事项
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();
}
上一篇:键盘坏了 (Ver. I)


下一篇:_MSC_VER 编译器版本