[bzoj1305][网络流]dance跳舞
来源:互联网 发布:js translate 做动画 编辑:程序博客网 时间:2024/05/02 03:07
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
题解
一开始想着二分图匹配。。但是想了想好像要跑k次不行啊
然后旁边大佬就跟我说这题是网络流,一想6666,想建模去。。
对于男生i和女生j,拆成两个点i.x,i.y和j.x,j.y
如果i喜欢j,那么i.x和j.x连边,流量为1因为只能匹配一次
不喜欢的话,那么i.y和j.y连边,流量同上
二分枚举最多能跳舞的次数,源点向i.x连边,流量为次数
j.x向汇点连边,流量同样为次数
i.x和j.x分别向i.y和j.y连边,流量为k
这样跑最大流验证就好了。。
真是神题我却打错了一个符号wa了一发
#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<cmath>using namespace std;struct node{ int x,y,c,next,other;}a[210000];int len,last[210000];void ins(int x,int y,int c){ int k1,k2; len++;k1=len; a[len].x=x;a[len].y=y;a[len].c=c; a[len].next=last[x];last[x]=len; len++;k2=len; a[len].x=y;a[len].y=x;a[len].c=0; a[len].next=last[y];last[y]=len; a[k1].other=k2;a[k2].other=k1;}int h[210000],list[210000];int st,ed,n,k;bool bt_h(){ memset(h,0,sizeof(h)); h[st]=1;list[1]=st; int head=1,tail=2; while(head!=tail) { int x=list[head]; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(a[k].c>0 && h[y]==0) { h[y]=h[x]+1; list[tail++]=y; } } head++; } if(h[ed]>0)return true; return false;}int find_flow(int x,int f){ if(x==ed)return f; int s=0,t; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(h[y]==h[x]+1 && a[k].c>0 && s<f) { s+=(t=find_flow(y,min(a[k].c,f-s))); a[k].c-=t;a[a[k].other].c+=t; } } if(s==0)h[x]=0; return s;}char map[60][60];/* boy1 1~n boy2 n+1~n+n girl1 n+n+1~n+n+n girl2 n+n+n+1~n+n+n+n*/bool check(int w){ len=0;memset(last,0,sizeof(last)); st=4*n+1;ed=4*n+2; for(int i=1;i<=n;i++) { ins(st,i,w);ins(i,i+n,k); for(int j=1;j<=n;j++) { if(map[i][j]=='Y')ins(i,j+2*n,1); else ins(i+n,j+3*n,1); } } for(int i=1;i<=n;i++)ins(i+3*n,i+2*n,k),ins(i+2*n,ed,w); int q=0; while(bt_h())q+=find_flow(st,999999999); if(w*n==q)return true; return false;}int main(){ scanf("%d%d",&n,&k); for(int i=1;i<=n;i++)scanf("%s",map[i]+1); int l=0,r=n,ans; while(l<=r) { int mid=(l+r)/2; if(check(mid)){ans=mid;l=mid+1;} else r=mid-1; } printf("%d\n",ans); return 0;}
阅读全文
0 0
- [bzoj1305][网络流]dance跳舞
- [BZOJ1305][CQOI2009]dance跳舞-网络流
- BZOJ1305 [CQOI2009]dance跳舞 【网络流】
- bzoj1305 [CQOI2009]dance跳舞 最大流 二分
- 【bzoj1305】[CQOI2009]dance跳舞 最大流
- 【BZOJ1305】[CQOI2009]dance跳舞【最大流】【二分】
- BZOJ1305 [CQOI2009]dance跳舞 最大流+二分
- 【二分+最大流】BZOJ1305 [CQOI2009]dance跳舞
- BZOJ1305 [CQOI2009]dance跳舞
- bzoj1305【CQOI2009】dance 跳舞
- bzoj1305[CQOI2009]dance跳舞
- bzoj1305: [CQOI2009]dance跳舞
- bzoj1305 [CQOI2009]dance跳舞
- 【bzoj1305】【CQOI2009】【dance】【跳舞】
- BZOJ1305: [CQOI2009]dance跳舞
- bzoj1305 [CQOI2009]dance跳舞
- bzoj1305[CQOI2009]dance跳舞
- bzoj1305: [CQOI2009]dance跳舞
- 玩转百度知道营销软件
- Mac下使文件标题栏显示绝对路径
- vi及vim入门(一)
- HashMap迭代器遍历
- vs2013编程错误总结
- [bzoj1305][网络流]dance跳舞
- 学习OpenCV(一)
- java设置JLabel字体字号颜色
- js实现将要复制的内容放到剪贴板里面
- java的InputStream和OutputStream的理解
- SpringMVC+Shiro权限管理
- 支持向量机SVM
- sqlserver2008修改列为主键时候发现设置主键是灰色的解决办法
- 独家 | 大数据与AI技术助力金融科技:百融金服的探索实例