您的位置:首页 > 其它

BZOJ 1305:dance跳舞(二分+最大流)

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

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

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

Sample Input
3 0
YYY
YYY
YYY
Sample Output
3
Hint
N<=50 K<=30


思路:二分答案,然后最大流。

建图:对于每个男生,拆成两个点A,B(而且A给B分流,流量为K):A用来连接喜欢的女生,B用来连接不喜欢的女生。很明显,二分到num时,给个A拥有num的流量,B拥有K流量。

同理:女生那里也要拆点。并且,男生流出的流和女生进入的流都要加num的限制。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int inf=10000000;
const int maxn=40010;
char mp[60][60];
int Laxt[maxn],Next[maxn],To[maxn],cap[maxn],cnt;
int dis[maxn],vd[maxn],S,N,T,K;
void add(int u,int v,int val)
{
Next[++cnt]=Laxt[u];
Laxt[u]=cnt;
To[cnt]=v;
cap[cnt]=val;
}
int sap(int u,int flow)
{
if(flow==0||u==T) return flow;
int tmp,delta=0;
for(int i=Laxt[u];i;i=Next[i]){
if(dis[u]==dis[To[i]]+1&&cap[i]>0){
tmp=sap(To[i],min(cap[i],flow-delta));
delta+=tmp;
cap[i]-=tmp;
cap[i^1]+=tmp;
if(delta==flow||dis[S]>T+1) return delta;
}
}
vd[dis[u]]--;
if(vd[dis[u]]==0) dis[S]=T+2;
vd[++dis[u]]++;
return delta;
}
bool check(int num)
{
int res=0; cnt=1;
for(int i=S;i<=T;i++) Laxt[i]=dis[i]=vd[i]=0;
for(int i=1;i<=N;i++) { add(S,i,num); add(i,S,0); } //分散给男生
for(int i=1;i<=N;i++) { add(i,N+i,K); add(N+i,i,0); } //给不喜欢的分配名额
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
if(mp[i][j]=='Y'){ add(i,3*N+j,1);add(3*N+j,i,0); } //给喜欢的女生分配
else { add(N+i,2*N+j,1); add(2*N+j,N+i,0);  }//给不喜欢的分配
for(int i=2*N+1;i<=2*N+N;i++){ add(i,N+i,K); add(T,i,0); } //汇聚到女生
for(int i=3*N+1;i<=3*N+N;i++){ add(i,T,num); add(T,i,0); } //汇聚到汇点
while(dis[S]<=T+1) res+=sap(S,inf);
if(res==num*N) return true;
return false;
}
int main()
{
scanf("%d%d",&N,&K); S=0; T=4*N+1;
for(int i=1;i<=N;i++) scanf("%s",mp[i]+1);
int L=0,R=N,Mid,ans=0;
while(L<=R){
Mid=(L+R)>>1;
if(check(Mid)) ans=Mid,L=Mid+1;
else R=Mid-1;
}
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: