[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
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 }
博主是蒟蒻,有问题请指出,谢谢!
本博客中博文均为原创,未经博主允许请勿随意转载,谢谢。
本博客中博文均为原创,未经博主允许请勿随意转载,谢谢。