一次舞会有n个男孩和n个女孩。每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞。每个男孩都不会和同一个女孩跳两首(或更多)舞曲。有一些男孩女孩相互喜欢,而其他相互不喜欢(不会“单向喜欢”)。每个男孩最多只愿意和k个不喜欢的女孩跳舞,而每个女孩也最多只愿意和k个不喜欢的男孩跳舞。给出每对男孩女孩是否相互喜欢的信息,舞会最多能有几首舞曲?
一次舞会有n个男孩和n个女孩。每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞。每个男孩都不会和同一个女孩跳两首(或更多)舞曲。有一些男孩女孩相互喜欢,而其他相互不喜欢(不会“单向喜欢”)。每个男孩最多只愿意和k个不喜欢的女孩跳舞,而每个女孩也最多只愿意和k个不喜欢的男孩跳舞。给出每对男孩女孩是否相互喜欢的信息,舞会最多能有几首舞曲?
第一行包含两个整数n和k。以下n行每行包含n个字符,其中第i行第j个字符为'Y'当且仅当男孩i和女孩j相互喜欢。
仅一个数,即舞曲数目的最大值。
N<=50 K<=30
加强数据By dwellings and liyizhen2
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int maxn = 50 * 10;
const int maxm = maxn * maxn * 10;
const int INF = 2147483647;
struct data{
int to,cap,flow;
}e[maxm];
vector G[maxn];
int ans,n,m,k,tot,s,t,tote = -1;
int cur[maxn],dis[maxn],Q[maxn];
int lx[maxn],ox[maxn],ly[maxn],oy[maxn];
int id[maxm],now;
inline LL getint()
{
LL ret = 0;
char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9')
ret = ret * 10 + c - '0',c = getchar();
return ret;
}
inline bool bfs()
{
memset(dis,-1,sizeof(dis));
memset(cur,0,sizeof(cur));
int head = 0,tail = 0;
dis[Q[++tail] = s] = 0;
while (head < tail)
{
int u = Q[++head];
for (int i = 0; i < G[u].size(); i++)
{
data E = e[G[u][i]];
if (dis[E.to] != -1 || E.flow == E.cap) continue;
dis[Q[++tail] = E.to] = dis[u] + 1;
}
}
return dis[t] != -1;
}
inline int dinic(int u,int a)
{
if (u == t || !a) return a;
int flow = 0;
for (int &i = cur[u]; i < G[u].size(); i++)
{
data &E = e[G[u][i]];
if (E.flow == E.cap || dis[E.to] != dis[u] + 1) continue;
int f = dinic(E.to,min(a,E.cap - E.flow));
if (!f) continue;
E.flow += f;
flow += f;
e[G[u][i] ^ 1].flow -= f;
a -= f;
if (!a) break;
}
return flow;
}
inline void add(int u,int v,int cap)
{
e[++tote] = (data){v,cap,0};
G[u].push_back(tote);
e[++tote] = (data){u,cap,cap};
G[v].push_back(tote);
}
inline char getcom()
{
char c = getchar();
while (c != 'Y' && c != 'N') c = getchar();
return c;
}
int main()
{
n = getint(); k = getint();
s = ++tot; t = ++tot;
for (int i = 1; i <= n; i++)
{
int tmp = ++tot;
add(s,tmp,0);
id[++now] = tote - 1;
add(tmp,lx[i] = ++tot,k);
add(tmp,ox[i] = ++tot,INF);
tmp = ++tot;
add(tmp,t,0);
id[++now] = tote - 1;
add(ly[i] = ++tot,tmp,k);
add(oy[i] = ++tot,tmp,INF);
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
char c = getcom();
if (c == 'Y') add(ox[i],oy[j],1);
else add(lx[i],ly[j],1);
}
for (int i = 1; i <= n + 1; i++)
{
for (int j = 1; j <= now; j++)
{
e[id[j]].cap++;
e[id[j] ^ 1].cap++;
e[id[j] ^ 1].flow++;
}
int ans = 0;
while (bfs())
ans += dinic(s,INF);
int flag = 0;
for (int j = 1; j <= now; j++)
if (e[id[j]].flow < e[id[j]].cap)
flag = 1;
if (flag)
{
printf("%d",i - 1);
break;
}
}
return 0;
}