[]
My 200th solved problem on BZOJ. So slow am I "brushing" problems.
[Solution]
It seems like a network flow problem. We can bin-enum the answer and check it.
Divide each person into two nodes. One stands for himself and the other one stands for dancing with those who he dislikes. Add an edge from himself to the other node sized K. For each answer, we add the edge from source to it self sized V, and if the max flow is V * N, the answer must be legal. Otherwise, it's illigal.
This is using a quality of a flow graph like this. If a flow is full, there must be matches that in each match, a node connects to a different node.
[Code]
#include <cstdio>
#include <algorithm>
#include <memory.h>
using namespace std;
struct edge {
int t, v, c;
edge *next, *rv;
};
const int maxn = 209;
const int maxe = 100009;
const int inf = 0x3f3f3f3f;
int n, k, st, te, d[maxn];
bool r[maxn][maxn];
edge *head[maxn], *ep, elst[maxe];
inline edge* addSingle(int u, int v, int c) {
ep-> t = v;
ep-> c = c;
ep-> next = head[u];
head[u] = ep;
return ep ++;
}
inline void addEdge(int u, int v, int c) {
edge *a = addSingle(u, v, c);
edge *b = addSingle(v, u, 0);
a-> rv = b;
b-> rv = a;
}
bool buildMap() {
static int q[maxn];
int hd = 0, tl = 1;
memset(d, 0, sizeof(d));
d[st] = 1;
q[0] = st;
while (hd < tl) {
int p = q[hd ++];
for (edge* e = head[p]; e; e = e-> next)
if (e-> c && !d[e-> t]) {
d[e-> t] = d[p] + 1;
q[tl ++] = e-> t;
}
}
return d[te];
}
int dfs(int p, int c) {
if (p == te)
return c;
int s = 0;
edge* e;
for (e = head[p]; e && c; e = e-> next)
if (e-> c && d[e-> t] == d[p] + 1) {
int x = dfs(e-> t, min(c, e-> c));
s += x;
c -= x;
e-> c -= x;
e-> rv-> c += x;
}
if (!e)
d[p] = 0;
return s;
}
bool check(int v) {
memset(head, 0, sizeof(head));
ep = elst;
for (int i = 0; i < n; i ++)
for (int j = 0; j < n; j ++)
if (r[i][j])
addEdge(i, j + n * 2, 1);
else
addEdge(i + n, j + n * 3, 1);
for (int i = 0; i < n; i ++)
addEdge(st, i, v), addEdge(i + n * 2, te, v);
for (int i = n; i < n * 2; i ++)
addEdge(i - n, i, k), addEdge(i + n * 2, i + n, k);
int ans = 0;
while (buildMap())
ans += dfs(st, inf);
return ans == v * n;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i ++) {
char l[maxn];
scanf("\n%s", l);
for (int j = 0; j < n; j ++)
r[i][j] = (l[j] == 'Y');
}
st = n * 4;
te = n * 4 + 1;
int l = 0, r = n;
while (l < r) {
int mid = (l + r + 1) >> 1;
if (check(mid))
l = mid;
else
r = mid - 1;
}
printf("%d\n", l);
}