列表

详情


NC19911. [CQOI2009]DANCE跳舞

描述

一次舞会有n个男孩和n个女孩。每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞。每个男孩都不会和同一个女孩跳两首(或更多)舞曲。有一些男孩女孩相互喜欢,而其他相互不喜欢(不会“单向喜欢”)。每个男孩最多只愿意和k个不喜欢的女孩跳舞,而每个女孩也最多只愿意和k个不喜欢的男孩跳舞。给出每对男孩女孩是否相互喜欢的信息,舞会最多能有几首舞曲?

输入描述

第一行包含两个整数n和k。
以下n行每行包含n个字符,其中第i行第j个字符为'Y'当且仅当男孩i和女孩j相互喜欢。

输出描述

仅一个数,即舞曲数目的最大值。

示例1

输入:

3 0
YYY
YYY
YYY

输出:

3

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 8ms, 内存消耗: 632K, 提交时间: 2020-03-27 18:17:06

#include<bits/stdc++.h>
using namespace std;
const int inf=1e9;
int ans;
int cnt;
int head[1010],q[1010],dis[1010];
int n,k,T;
struct edge
{
	int to,nxt;
	int flow;
}e[500050];
inline void addedge(int x,int y,int fl)
{
	e[++cnt].to=y;
	e[cnt].nxt=head[x];
	head[x]=cnt;
	e[cnt].flow=fl;
	e[++cnt].to=x;
	e[cnt].nxt=head[y];
	head[y]=cnt;
	e[cnt].flow=0;
}
bool mp[1010][1010];
inline bool bfs()
{
	int ql=0,qr=1;
	q[1]=0;
	memset(dis,0,sizeof(dis));
	dis[0]=1;
	while(ql<qr)
	{
		int x=q[++ql];
		for(int i=head[x];i;i=e[i].nxt)
		{
			int y=e[i].to;
			if(e[i].flow&&!dis[y])
			{
				dis[y]=dis[x]+1;
				q[++qr]=y;
			}
		}
	}
	if(dis[T]) return true;
	return false;
}
inline int dfs(int x,int flow)
{
	if(x==T) return flow;
	int d,used=0;
	for(int i=head[x];i;i=e[i].nxt)
	{
		int y=e[i].to;
		if(e[i].flow&&dis[y]==dis[x]+1)
		{
			d=dfs(y,min(flow,e[i].flow));
			e[i].flow-=d;
			e[i^1].flow+=d;
			used+=d;
			if(used==flow)
			return flow;
		}
	}
	if(!used)
	dis[x]=-1;
	return used;
 } 
inline void dinic()
{
	while(bfs())
	ans+=dfs(0,inf);
}
inline void build(int x)
{
	cnt=1;
	memset(head,0,sizeof(head));
	for(int i=1;i<=n;i++)
    {
    	addedge(0,i,x);
    	addedge(i,i+500,k);
    	addedge(i+n+500,i+n,k);
    	addedge(i+n,T,x);
	}
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	if(mp[i][j]) addedge(i,n+j,1);
	else addedge(i+500,n+j+500,1);
}
int main()
{
	scanf("%d%d",&n,&k);
	T=1001;
	for(int i=1;i<=n;i++)
	{
		char ch[51];
		scanf("%s",ch);
		for(int j=1;j<=n;j++)
		if(ch[j-1]=='Y')
		mp[i][j]=1;
	}
	int mx=0,l=0,r=50;
	while(l<=r)
	{
		int mid=l+r>>1;
		build(mid);
		ans=0;
		dinic();
		if(ans>=n*mid)
		mx=mid,l=mid+1;
		else
		r=mid-1;
	}
	cout<<mx;
}

上一题