BZOJ1305 [CQOI2009]dance跳舞

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ1305 [CQOI2009]dance跳舞相关的知识,希望对你有一定的参考价值。

Description

一次舞会有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

 
把男孩女孩都拆点为x,y
S向x连边,容量为a,y向汇点连边,容量为a
a可以二分,可以枚举(反正只有30)
男生x-->y连边为k,女生y-->x连边为k,男生喜欢女生在左部连边,反之在右部
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<iostream>
 5 using namespace std;
 6 const int inf=100000000,N=1005;
 7 struct ee{int to,next,f;}e[500001];
 8 int head[N],q[N*2],dis[N],map[N][N];
 9 int S,T,n,m,cnt=1,ans,w,k,mx;
10    
11 void ins(int u,int v,int f){
12     e[++cnt].to=v;e[cnt].f=f;e[cnt].next=head[u];head[u]=cnt;
13     e[++cnt].to=u;e[cnt].f=0;e[cnt].next=head[v];head[v]=cnt;
14 }
15    
16 bool bfs(){
17     for (int i=1;i<=T;i++) dis[i]=inf;
18     int h=0,t=1,now;
19     q[1]=S;dis[S]=0;
20     while(h!=t){
21         now=q[++h];
22         for (int i=head[now];i;i=e[i].next){
23             int v=e[i].to;
24             if (e[i].f&&dis[now]+1<dis[v]){
25                 dis[v]=dis[now]+1;
26                 if (v==T)return 1;
27                 q[++t]=v;
28             }
29         }
30     }
31     if (dis[T]==inf) return 0; return 1;
32 }
33    
34 int dinic(int now,int f){
35     if (now==T) return f;
36     int rest=f;
37     for (int i=head[now];i;i=e[i].next){
38         int v=e[i].to;
39         if (e[i].f&&dis[v]==dis[now]+1&&rest){
40             int t=dinic(v,min(rest,e[i].f));
41             if (!t) dis[v]=0;
42             e[i].f-=t;
43             e[i^1].f+=t;
44             rest-=t;
45         }
46     }
47     return f-rest;
48 }
49 void build(int f){
50     cnt=1;
51     memset(head,0,sizeof(head));
52     for(int i=1;i<=n;i++) ins(S,i,f);
53     for(int i=n+1;i<=2*n;i++) ins(i,T,f);
54     for(int i=1;i<=n;i++) ins(i,i+2*n,k);
55     for(int i=n+1;i<=2*n;i++) ins(i+2*n,i,k);
56     for(int i=1;i<=n;i++)
57         for(int j=1;j<=n;j++){
58             if(map[i][j]) ins(i,j+n,1);
59             else ins(i+2*n,j+3*n,1);
60         } 
61 }
62 int main(){
63     scanf("%d%d",&n,&k);
64     T=4*n+1;
65     char s[100];
66     for(int i=1;i<=n;i++){
67         scanf("%s",s+1);
68         for(int j=1;j<=n;j++)
69             if(s[j]==Y) map[i][j]=1;
70     }
71     int l=0,r=50;
72     while(l<=r)
73     {
74         int mid=(l+r)>>1;
75         build(mid);
76         ans=0;while(bfs()) ans+=dinic(S,inf);
77         if(ans>=n*mid){mx=mid;l=mid+1;}
78         else r=mid-1;
79     }
80     printf("%d",mx);
81 } 

 

以上是关于BZOJ1305 [CQOI2009]dance跳舞的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1305 [CQOI2009]dance跳舞(二分+网络流)

[bzoj1305][CQOI2009]dance跳舞

BZOJ1305: [CQOI2009]dance跳舞

bzoj千题计划130:bzoj1305: [CQOI2009]dance跳舞

[BZOJ1305][CQOI2009]跳舞(网络流)

bzoj 1305: [CQOI2009]dance跳舞