为什么流会是0呢?
查看原帖
为什么流会是0呢?
22716
神仙酱楼主2024/6/26 14:30
#include <bits/stdc++.h>
using namespace std;
const int N = 2000, M = 1e5 + 10, INF = 0x3f3f3f3f;
int n, m, cnt, s, t;
int h[N], nxt[M], e[M], idx = 2, w[M], cur[N];
int mp[60][60];
int gap[N], dep[N];
namespace details {
    void add(int a, int b, int c) {
        e[idx] = b, w[idx] = c, nxt[idx] = h[a], cur[a] = h[a] = idx++;
    }
}  // namespace details

void add(int a, int b, int c) {
    details::add(a, b, c), details::add(b, a, 0);
}

void bfs() {
    queue<int> q;
    q.push(t);
    memset(dep, -1, sizeof dep);
    gap[dep[t] = 0] = 1;
    while (q.size()) {
        int u = q.front();
        q.pop();
        for (int i = h[u]; i; i = nxt[i]) {
            int j = e[i];
            if (dep[j] == -1) {
                gap[dep[j] = dep[u] + 1]++;
                q.push(j);
            }
        }
    }
}

int dfs(int u, int flow) {
   if (u == t)
        return flow;
    int used = 0;
    for (int i = h[u]; i; i = nxt[i]) {
        cur[u] = i;
        int j = e[i];
        if (dep[j] == dep[u] - 1 && w[i] > 0) {
            int f = dfs(j, min(w[i], flow - used));
            w[i] -= f, w[i ^ 1] += f;
            used += f;
            if (used == flow) {
                cur[u] = h[u];
                return flow;
            }
        }
    }
    cur[u] = h[u];
    if (!--gap[dep[u]])
        dep[s] = n * m * 2 - cnt + 2;
    ++gap[++dep[u]];
    return used;
}

int isap() {
    int maxflow = 0;
    bfs();
    while (dep[s] < n * m * 2 - cnt + 2)
        maxflow += dfs(s, 1 << 29);
    return maxflow;
}

int point1(int i, int j) {
    return (i - 1) * n + j;
}

int point2(int i, int j) {
    return point1(i, j) + n * m;
}

signed main() {
#ifndef ONLINE_JUDGE
    freopen(".in", "r", stdin);  // freopen(".out", "w", stdout);
#else
    cin.tie(0)->sync_with_stdio(0);
#endif
    cin >> m >> n;
    s = N - 5, t = s + 1;
    int dx[] = { 1, -1, 0, 0 }, dy[] = { 0, 0, 1, -1 };
    for (int i = 1; i <= m; ++i) {
        for (int j = 1; j <= n; ++j) {
            cin >> mp[i][j];
            if (mp[i][j] == 0) {
                add(s, point1(i, j), INF);
                cnt++;
            }
            else if (mp[i][j] != -1) {
                for (int k = 0; k < 4; ++k) {
                    int x = dx[k] + i, y = dy[k] + j;
                    if (x >= 1 && x <= m && y >= 1 && y <= n && mp[x][y] >= 0) {
                        add(point2(i, j), point1(x, y), INF);
                    }
                }
                add(point1(i, j), point2(i, j), mp[i][j]);
            }
            else
                cnt += 2;
            if (i == 1 || j == 1 || i == m || j == n)
                add(point2(i, j), t, INF);
        }
    }

    cout << isap();

    return 0;
}
2024/6/26 14:30
加载中...