82分求助
查看原帖
82分求助
833124
BIOS楼主2023/9/20 19:36
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int N = 1e4 + 5, M = 1e6 + 5, INF = 0x3f3f3f3f;
int h[N], e[M], ne[M], w[M], d[N], cur[N];
int n, m, k, cnt, S, T, res, idx, x, y, c, a, b;
char ch;
void add(int a, int b, int c)
{
    e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
    e[idx] = a, ne[idx] = h[b], w[idx] = 0, h[b] = idx++;
}
bool bfs()
{
    memset(d, -1, sizeof(d));
    queue<int> q;
    q.push(S), d[S] = 0, cur[S] = h[S];
    while (q.size())
    {
        int t = q.front();
        q.pop();
        for (int i = h[t]; ~i; i = ne[i])
        {
            int j = e[i];
            if (d[j] == -1 && w[i])
            {
                d[j] = d[t] + 1, cur[j] = h[j];
                if (j == T)
                    return true;
                q.push(j);
            }
        }
    }
    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])
    {
        int j = e[i];
        cur[u] = i;
        if (d[j] == d[u] + 1 && w[i])
        {
            int t = find(j, min(limit - flow, w[i]));
            if (!t)
                d[j] = -1;
            w[i] -= t, w[i ^ 1] += t, flow += t;
        }
    }
    return flow;
}
int Dinic()
{
    int r = 0, flow;
    while (bfs())
        while (flow = find(S, INF))
            r += flow;
    return r;
}
int main()
{
    cin >> n >> k, memset(h, -1, sizeof(h));
    S = 0, cnt = 2 * n, T = ++cnt;
    for (int i = 1; i <= n; i++)
    {
        add(S, i, 1), add(i + n, T, 1), add(i, ++cnt, k);
        for (int j = 1; j <= n; j++)
        {
            cin >> ch;
            if (ch == 'Y')
                add(i, j + n, 1);
            else
                add(cnt, j + n, 1);
        }
    }
    for (int flow = 1;; flow++)
    {
        res = Dinic();
        if (res < n)
            cout << flow - 1 << endl, exit(0);
        for (int i = 0; i < idx; i += 2)
        {
            a = e[i ^ 1], b = e[i];
            if (a == S || b == T)
                w[i] = 1, w[i ^ 1] = 0;
        }
    }
}

不是很懂为什么WA两个,思路是建立新点专门负责跟不喜欢的女生配对,分配k流量。

保留非S,T关联边(每次只重新分男女生次数,保留历史配对)的流量,然后反复求增广路

2023/9/20 19:36
加载中...