Shoot the Bullet [ZOJ - 3229] [Maximum Flow at Upper and Lower Bounds of Active Sinks]

Posted by rkeppert on Sat, 22 Feb 2020 03:23:00 +0100

Title Link

Title: For N days, M girls, followed by a row of M, indicating that M girls require you to take at least Gi photos of them in total in N days.Then there will be N days, every day there will be Ci and Di, indicating that there are Ci girlfriend paper to take today, but today the maximum number of Di photos will be taken, followed by Ci girlfriend paper, the first is the number of girlfriend paper, 0-M-1, then L-R, indicating that this girlfriend paper requires you to take at least L photos and at most R photos.


This question, because I did not write the top height of ISAP exit well, has been WA dozens of times, plus a whole night of self-closure.

Finally, I added 1 to my top, and that's it.Here the ISAP height must be node + 1, and there are nodes starting from 0, so we must update the update to 0~node+2, why is "node+2", because node+2 is the first infeasible height.Must be initialized to node+2.

There are so many aspects of ISAP that the next step is to think about how to solve the problem.

First, each girlfriend paper takes at least a total of Gi photos, that is, the lower limit is determined to be Gi, so here the lower limit is processed first;

Again, we know the upper limit for at least 0 and at most Di photos per day;

Then, each girlfriend paper takes Li-Ri pictures every day, indicating that there are limits.

Thus, according to the above rules, we can determine how to build a map, and then we can run a maximum flow directly. Whether the maximum flow *2 equals the sum of | inflow-outflow | is the criterion to judge whether there is a solution or not.

When we have a solution, we delete the super source and sink, turn the original source and sink into the current source and sink, and run the maximum flow again to know the flow rate of each edge, plus the lower limit, which is the actual flow of each edge.

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <unordered_map>
#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x7f7f7f7f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 1505, maxM = 8e5 + 7;
int N, M, head[maxN], cnt, du[maxN], _Index, line[maxM], fl[maxM], sum;
struct Eddge
    int nex, to, flow;
    Eddge(int a=-1, int b=0, int c=0):nex(a), to(b), flow(c) {}
inline void addEddge(int u, int v, int f)
    edge[cnt] = Eddge(head[u], v, f);
    head[u] = cnt++;
inline void _add(int u, int v, int f) { addEddge(u, v, f); addEddge(v, u, 0); }
struct ISAP
    int S, T, gap[maxN], cur[maxN], deep[maxN], que[maxN], ql, qr;
    inline void init()
        for(int i=0; i<=T + 2; i++)
            gap[i] = deep[i] = 0;
            cur[i] = head[i];
        ++gap[deep[T] = 1];
        que[ql = qr = 1] = T;
        while(ql <= qr)
            int u = que[ql ++];
            for(int i=head[u], v; ~i; i=edge[i].nex)
                v = edge[i].to;
                if(!deep[v]) { ++gap[deep[v] = deep[u] + 1]; que[++qr] = v; }
    inline int aug(int u, int Flow)
        if(u == T) return Flow;
        int flow = 0;
        for(int &i = cur[u], v; ~i; i=edge[i].nex)
            v = edge[i].to;
            if(deep[u] == deep[v] + 1)
                int tmp = aug(v, min(edge[i].flow, Flow));
                flow += tmp; Flow -= tmp; edge[i].flow -= tmp; edge[i ^ 1].flow += tmp;
                if(!Flow) return flow;
        if(!(--gap[deep[u]])) deep[S] = T + 2;
        ++gap[++deep[u]]; cur[u] = head[u];
        return flow;
    inline int Max_Flow()
        int ret = aug(S, INF);
        while(deep[S] <= T + 1) ret += aug(S, INF);
        return ret;
} mf;
inline void init()
    cnt = 0; mf.S = N + M + 2; mf.T = N + M + 3; _Index = 0; sum = 0;
    for(int i=0; i<=N + M + 3; i++) { head[i] = -1; du[i] = 0; }
int main()
    while(scanf("%d%d", &N, &M) != EOF)
        int s = 0, t = N + M + 1;
        for(int i=1, Gi; i<=M; i++)
            scanf("%d", &Gi);
            _add(i + N, t, INF);
            du[i + N] -= Gi; du[t] += Gi;
        for(int day = 1, Ci, Di; day <= N; day++)
            scanf("%d%d", &Ci, &Di);
            _add(s, day, Di);
            for(int i=1, id, l, r; i<=Ci; i++)
                scanf("%d%d%d", &id, &l, &r); id += N + 1;
                _add(day, id, r - l);
                du[day] -= l; du[id] += l;
                line[++_Index] = cnt - 1; fl[_Index] = l;
        for(int i=0; i<=t; i++)
            if(du[i] > 0)
                _add(mf.S, i, du[i]);
                sum += du[i];
            else if(du[i] < 0)
                _add(i, mf.T, -du[i]);
                sum -= du[i];
        _add(t, s, INF);
        if(mf.Max_Flow() * 2 != sum) { printf("-1\n\n"); continue; }
        head[mf.S] = head[mf.T] = -1;
        mf.S = s; mf.T = t;
        printf("%d\n", mf.Max_Flow());
        for(int i=1; i<=_Index; i++)
            printf("%d\n", fl[i] + edge[line[i]].flow);
    return 0;


803 original articles published, 964 praised, 90,000 visits+
His message board follow