[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

 

Source

加强数据By dwellings and liyizhen2

 这数据。。。

正解好像是要二分一下答案,然后判断满流,然而我枚举答案也能过。。。

枚举一次答案都要连一次边。。(不连好像也行,but i am lazy)

将每个人拆点,拆成“和喜欢的人跳”的点(A)和“和不喜欢的人跳”的点(B)。

对于男孩,连接S和A,流量为枚举的(二分的)答案x,再连接A和B,流量为k,可以保证每个人都只跳了x首舞曲。

对于女孩,连接A和T,流量为枚举的(二分的)答案x,再连接B和A,流量为k,可以保证每个人都只跳了x首舞曲。(Ctrl+v)

女孩连边方式和男孩是反的。

对于每对人a,b(a男,b女),如果相互喜欢,就连接aA,bA,否则连接aB,bB

判断流量是否为x*n...

 1 // It is made by XZZ
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 #define rep(a,b,c) for(rg int a=b;a<=c;a++)
 7 #define drep(a,b,c) for(rg int a=b;a>=c;a--)
 8 #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
 9 #define il inline
10 #define rg register
11 #define vd void
12 #define t (dis[i])
13 typedef long long ll;
14 il int gi(){
15     rg int x=0;rg char ch=getchar();
16     while(ch<'0'||ch>'9')ch=getchar();
17     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
18     return x;
19 }
20 const int maxn=203,maxm=(maxn+maxn+maxn*maxn)<<1,S=0,T=201;
21 int fir[maxn],dis[maxm],nxt[maxm],w[maxm],head[maxn],dep[maxn],id=1;
22 il vd add(int a,int b,int c){
23     nxt[++id]=fir[a],fir[a]=id,dis[id]=b,w[id]=c;
24     if(c)add(b,a,0);
25 }
26 char yes[53][53];
27 
28 il bool BFS(){
29     rg int que[maxn],hd=0,tl=1;
30     memset(dep,0,sizeof dep);
31     que[hd]=S,dep[S]=1;
32     while(hd-tl){
33     int now=que[hd++];
34     erep(i,now)if(!dep[t]&&w[i])que[tl++]=t,dep[t]=dep[now]+1;
35     }
36     return dep[T];
37 }
38 il int Dinic(int now,int maxflow){
39     if(now==T)return maxflow;
40     rg int ret=0;
41     for(rg int&i=head[now];i;i=nxt[i])if(w[i]&&dep[t]==dep[now]+1){
42     rg int d=Dinic(t,min(maxflow,w[i]));
43     w[i]-=d,w[i^1]+=d,maxflow-=d,ret+=d;
44     if(!maxflow)break;
45     }return ret;
46 }
47 int main(){
48     int n=gi(),k=gi();
49     rep(i,1,n)scanf("%s",yes[i]+1);
50     rep(x,1,n){
51         id=1;memset(fir,0,sizeof fir);
52     rep(i,1,n)add(S,i,x),add(i+n,T,x),add(i,i+n+n,k),add(i+n+n+n,i+n,k);
53         rep(i,1,n)rep(j,1,n)if(yes[i][j]=='Y')add(i,j+n,1);else add(i+n+n,j+n+n+n,1);
54     int flow=0;
55     while(BFS())memcpy(head,fir,sizeof fir),flow+=Dinic(S,23333);
56     if(flow!=x*n){printf("%d\n",x-1);return 0;}
57     }printf("%d\n",n);
58     return 0;
59 }
View Code

 

posted @ 2017-07-30 09:27  菜狗xzz  阅读(168)  评论(0编辑  收藏  举报