#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int N = 500, M = 2e6 + 5, INF = 0x3f3f3f3f;
int h[N], e[M], ne[M], w[M], d[N], cur[N], n;
int idx, S, T, a1, a2, an, b1, b2, bn, res1, res2;
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()
{
queue<int> q;
memset(d, -1, sizeof(d));
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()
{
while (cin >> n >> a1 >> a2 >> an >> b1 >> b2 >> bn)
{
a1++, a2++, b1++, b2++;
memset(h, -1, sizeof(h)), idx = S = 0, T = 2 * n + 1;
add(S, a1, an), add(a1 + n, T, an), add(S, b1, bn), add(b1 + n, T, bn);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
cin >> ch;
if (ch == 'O')
add(i, j, 2), add(j + n, i + n, 2);
else if (ch == 'N')
add(i, j, INF), add(j + n, i + n, INF);
}
add(a2, a2 + n, an), add(b2, b2 + n, bn);
int res = Dinic();
cout << "res:" << res << endl;
if (res == an + bn)
cout << "Yes\n";
else
cout << "No\n";
}
}
难道我理解错了吗,感觉代码写的很清晰了。思路是把一个来回拆成正向路和反向路,以[1,n]和[n+1,2n]为两个领域,以a2和b2为衔接,同时规定了an,bn的流量限制跑最大流。然而输出的最大流一直是满的...