#6224. The benefits of deep-sea robot problem "network flow 24" can be walked many times at a time

Title Link
meaning of the title
In the grid of P*Q, the income of each edge, the starting position and destination of several robots are given. The robot can only walk to the east or North, each side can walk many times, but it can only calculate the income once, and find the maximum income under the optimal robot movement scheme.
thinking
With the number of robots and the benefit of the edge, this problem obviously gives priority to the maximum cost and the maximum flow. The revenue of one edge can only be recorded once, and one edge with the capacity of 1 and the cost of 1 as the weight value can be connected. Then, the revenue of each edge can only be recorded once, but multiple robots can follow the same path, so for each edge, add an edge with the capacity of INF and the cost of 0. Set up super source point S and super sink point T. start point of all points of S connection. The capacity is the number of robots, the cost is 0, the cost of all destination points is t, and the capacity is the number of robots, the cost is 0. Then run the maximum cost flow, where the template is the minimum cost maximum flow, but change the cost of all sides to a negative value to get the maximum cost.

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int N = 5e3 + 7;
const int M = 1e4 + 7;
const int maxn = 1e3 + 7;
typedef long long ll;
int maxflow, mincost;
struct Edge {
    int from, to, cap, flow, cost;
    Edge(int u, int v, int ca, int f, int co):from(u), to(v), cap(ca), flow(f), cost(co){};
};
struct MCMF
{
    int n, m, s, t;
    vector<Edge> edges;
    vector<int> G[N];
    int inq[N], d[N], p[N], a[N];//Whether an arc can be improved on the queue distance
    void init(int n) {
        this->n = n;
        for (int i = 0; i < n; i++) G[i].clear();
        edges.clear();
    }
    void add(int from, int to, int cap, int cost) {
        edges.push_back(Edge(from, to, cap, 0, cost));
        edges.push_back(Edge(to, from, 0, 0, -cost));
        int m = edges.size();
        G[from].push_back(m - 2);
        G[to].push_back(m - 1);
    }
    bool SPFA(int s, int t, int &flow, int &cost) {
        for (int i = 0; i < N; i++) d[i] = INF;
        memset(inq, 0, sizeof(inq));
        d[s] = 0; inq[s] = 1; p[s] = 0; a[s] = INF;
        queue<int> que;
        que.push(s);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            inq[u]--;
            for (int i = 0; i < G[u].size(); i++) {
                Edge& e = edges[G[u][i]];
                if(e.cap > e.flow && d[e.to] > d[u] + e.cost) {
                    d[e.to] = d[u] + e.cost;
                    p[e.to] = G[u][i];
                    a[e.to] = min(a[u], e.cap - e.flow);
                    if(!inq[e.to]) {
                        inq[e.to]++;
                        que.push(e.to);
                    }
                }
            }
        }
        if(d[t] == INF) return false;
        flow += a[t];
        cost += d[t] * a[t];
        int u = t;
        while (u != s) {
            edges[p[u]].flow += a[t];
            edges[p[u]^1].flow -= a[t];
            u = edges[p[u]].from;
        }
        return true;
    }
    int MinMaxflow(int s, int t) {
        int flow = 0, cost = 0;
        while (SPFA(s, t, flow, cost));
        maxflow = flow; mincost = cost;
        return cost;
    }
};
int id[maxn][maxn];
int main()
{
    int n, m, s, t, a, b;
    scanf("%d%d%d%d", &a, &b, &n, &m);
    MCMF solve;
    int tot = 0;
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= m; j++)
            id[i][j] = ++tot;
    }
    for (int i = 0; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            int x;
            scanf("%d", &x);
            solve.add(id[i][j - 1], id[i][j], 1, -x);
            solve.add(id[i][j - 1], id[i][j], INF, 0);
        }
    }
    for (int j = 0; j <= m; j++) {
        for (int i = 1; i <= n; i++) {
            int x;
            scanf("%d", &x);
            solve.add(id[i - 1][j], id[i][j], 1, -x);
            solve.add(id[i - 1][j], id[i][j], INF, 0);
        }
    }
    s = id[n][m] + 1, t = s + 1;
    for (int i = 1; i <= a; i++) {
        int k, x, y;
        scanf("%d%d%d", &k, &x, &y);
        solve.add(s, id[x][y], k, 0);
    }
    for (int i = 1; i <= b; i++) {
        int k, x, y;
        scanf("%d%d%d", &k, &x, &y);
        solve.add(id[x][y], t, k, 0);
    }
    printf("%d\n", -solve.MinMaxflow(s, t));
}

Published 31 original articles, won praise 2, visited 3518
Private letter follow

Posted by agallo on Wed, 29 Jan 2020 08:19:06 -0800