ISAP究竟为什么只对了一个点呢?已经检查很多遍了
查看原帖
ISAP究竟为什么只对了一个点呢?已经检查很多遍了
22716
神仙酱楼主2024/5/8 23:28
#include <algorithm>
#include <cstring>
#include <iostream>
#include <numeric>
#include <queue>
#include <sstream>
using namespace std;
const int N = 110, M = N * N, INF = 0x3f3f3f3f;
int e[M], h[N], nxt[M], w[M], idx = 2;
int cur[N], dep[N], gap[N];
long long maxflow;
int n, m, s, t;
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;
    memset(dep, -1, sizeof dep);
    gap[0] = 1, dep[t] = 0;
    q.push(t);
    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 = cur[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));
            used += f;
            w[i] -= f, w[i ^ 1] += f;
            if (used == flow)
                return flow;
        }
    }
    cur[u] = h[u];
    if (!--gap[dep[u]])
        dep[s] = n + m;
    ++gap[++dep[u]];
    return used;
}

void isap() {
    bfs();
    while (dep[s] < n + m)
        maxflow += dfs(s, INF);
}

int sponsor[N], cost[N];

int main() {
#ifndef ONLINE_JUDGE
    freopen(".in", "r", stdin);
    // freopen("a.out", "w", stdout);
#else
    cin.tie(0)->sync_with_stdio(0);
#endif
    cin >> m >> n;
    string str;
    getline(cin, str);
    s = n + m + 1, t = s + 1;
    for (int i = 1; i <= m; ++i) {
        getline(cin, str);
        stringstream ss(str);
        ss >> sponsor[i];
        add(s, i, sponsor[i]);
        int k = 0;
        for (int p; ss >> p; k++)
            add(i, p + m, INF);
    }
    for (int i = m + 1; i <= n + m; ++i) {
        cin >> cost[i - m];
        add(i, t, cost[i - m]);
    }

    isap();
    int total = 0;
    for (int i = h[s]; i; i = nxt[i]) {
        if (w[i]) {
            cout << e[i] << " ";
            total += sponsor[e[i]];
        }
    }
    cout << "\n";
    for (int i = h[t]; i; i = nxt[i]) {
        if (cost[e[i] - m] == w[i])
            cout << e[i] - m << " ";
    }
    cout << "\n";
    cout << total - maxflow;
}
2024/5/8 23:28
加载中...