您的位置:首页 > 其它

1305: [CQOI2009]dance跳舞

2016-03-12 23:01 323 查看
#include<cstdio>
#include<iostream>
#include<cstring>
#define M 1000
#define inf 0x7fffffff
using namespace std;
int T,n,k,sum,cnt=1,head[M],next[10*M],u[10*M],v[10*M],d[2*M],q[2*M],mp[M][M];
char ch[66];
void jia(int a1,int a2,int a3)
{
cnt++;
u[cnt]=a2;
v[cnt]=a3;
next[cnt]=head[a1];
head[a1]=cnt;
return;
}
bool bfs()
{
memset(d,0,sizeof(int)*(T+2));
int h=0,t=1;
q[1]=0;
d[0]=1;
for(;h<t;)
{
h++;
int p=q[h];
for(int i=head[p];i;i=next[i])
if(!d[u[i]]&&v[i])
{
d[u[i]]=d[p]+1;
if(d[T])
return 1;
t++;
q[t]=u[i];
}
}
return 0;
}
int dinic(int s,int f)
{
if(s==T)
return f;
int rest=f;
for(int i=head[s];i&&rest;i=next[i])
if(v[i]&&d[u[i]]==d[s]+1)
{
int now=dinic(u[i],min(rest,v[i]));
if(!now)
d[u[i]]=0;
v[i]-=now;
v[i^1]+=now;
rest-=now;
}
return f-rest;
}
bool pan(int a1)
{
memset(head,0,sizeof(head));
cnt=1;
for(int i=1;i<=n;i++)
{
jia(0,i,a1);
jia(i,0,0);
jia(i,n+i,k);
jia(n+i,i,0);
jia(3*n+i,T,a1);
jia(T,3*n+i,0);
jia(2*n+i,3*n+i,k);
jia(3*n+i,2*n+i,0);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(mp[i][j])
{
jia(i,3*n+j,1);
jia(3*n+j,i,0);
}
else
{
jia(n+i,2*n+j,1);
jia(2*n+j,n+i,0);
}
sum=0;
for(;bfs();)
sum+=dinic(0,inf);
if(sum<a1*n)
return 0;
return 1;
}
int main()
{
scanf("%d%d",&n,&k);
T=(4*n)+1;
for(int i=1;i<=n;i++)
{
scanf("%s",ch+1);
for(int j=1;j<=n;j++)
if(ch[j]=='Y')
mp[i][j]=1;
}
int l=0,r=50,ans=0;
for(;l<=r;)
{
int mid=(l+r)>>1;
if(pan(mid))
{
l=mid+1;
ans=l;
}
else
r=mid-1;
}
printf("%d\n",ans-1);
return 0;
}


网络流 将男女进行拆点,二分答案,同一个人之间建容量k的边,源汇分别向男女连mid的边,再根据喜欢不喜欢对男女进行连边,使如果不喜欢的话要走同一个人之间的那一条边,最后

观察一下是否满流。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: