Time Limit: 5 Sec  Memory Limit: 162 MB
Submit: 2925  Solved: 1221

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

网络流 最大流判定+二分+拆点

二分答案,假设可以跳lim首舞曲,那么每个人要有lim个不同的舞伴

每个人拆成三个点n1,n2,n3

从S到每个男生的n1连边,容量为lim,限制此人需要有lim个不同舞伴

从每个男生的n1到n2连边,容量为INF,表示和喜欢的人跳舞的次数没有限制

从每个男生的n1到n3连边,容量为k,表示最多和不喜欢的人跳舞的次数为k

从每个女生的n1到T连边,容量为lim;

从每个女生的n2到n1连边,容量为INF,n3到n1连边,容量为k

从每个男生向每个女生连边,如果喜欢则n2连n2,否则n3连n3,容量为1,表示只和同一个人跳一支舞

跑最大流,如果最大流等于lim*n,说明每个人都找到了lim个舞伴,可行

  1. /*by SilverN*/
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdio>
  6. #include<cmath>
  7. #include<vector>
  8. #include<queue>
  9. using namespace std;
  10. const int INF=1e9;
  11. const int mxn=;
  12. int read(){
  13. int x=,f=;char ch=getchar();
  14. while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
  15. while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
  16. return x*f;
  17. }
  18. struct edge{
  19. int v,nxt,f;
  20. }e[mxn*mxn*];
  21. int hd[mxn],mct=;
  22. char mp[][];
  23. void add_edge(int u,int v,int f){
  24. e[++mct].v=v;e[mct].nxt=hd[u];e[mct].f=f;hd[u]=mct;return;
  25. }
  26. void insert(int u,int v,int f){
  27. add_edge(u,v,f);
  28. add_edge(v,u,);
  29. return;
  30. }
  31. int n,m,S,T;
  32. int d[mxn];
  33. bool BFS(){
  34. memset(d,,sizeof d);
  35. queue<int>q;
  36. d[S]=;
  37. q.push(S);
  38. while(!q.empty()){
  39. int u=q.front();q.pop();
  40. for(int i=hd[u];i;i=e[i].nxt){
  41. int v=e[i].v;
  42. if(e[i].f && !d[v]){
  43. d[v]=d[u]+;
  44. q.push(v);
  45. }
  46. }
  47. }
  48. return d[T];
  49. }
  50. int DFS(int u,int lim){
  51. if(u==T)return lim;
  52. int f=,tmp;
  53. for(int i=hd[u];i;i=e[i].nxt){
  54. int v=e[i].v;
  55. if(d[v]==d[u]+ && e[i].f){
  56. tmp=DFS(v,min(lim,e[i].f));
  57. e[i].f-=tmp;
  58. e[i^].f+=tmp;
  59. f+=tmp;
  60. lim-=tmp;
  61. if(!lim)return f;
  62. }
  63. }
  64. d[u]=;
  65. return f;
  66. }
  67. int Dinic(){
  68. int res=;
  69. while(BFS())res+=DFS(S,INF);
  70. return res;
  71. }
  72. void Build(int lim){
  73. int ed=n+n;
  74. int i,j;
  75. for(i=;i<=n;i++){//跳舞数量
  76. insert(S,i,lim);
  77. insert(i,i+ed,INF);
  78. insert(i,i+ed+ed,m);
  79. }
  80. for(i=;i<=n;i++){
  81. insert(i+n,T,lim);
  82. insert(i+n+ed,i+n,INF);
  83. insert(i+n+ed+ed,i+n,m);
  84. }
  85. for(i=;i<=n;i++)
  86. for(j=;j<=n;j++){
  87. if(mp[i][j]=='Y'){
  88. insert(i+ed,j+n+ed,);
  89. }
  90. else insert(i+ed+ed,j+n+ed+ed,);
  91. }
  92. return;
  93. }
  94. void init(){
  95. memset(hd,,sizeof hd);
  96. mct=;
  97. return;
  98. }
  99. int ans=;
  100. void solve(){
  101. int l=,r=;
  102. while(l<=r){
  103. int mid=(l+r)>>;
  104. init();
  105. Build(mid);
  106. int res=Dinic();
  107. if(res==mid*n){
  108. ans=mid;
  109. l=mid+;
  110. }else r=mid-;
  111. }
  112. return;
  113. }
  114. int main(){
  115. int i,j;
  116. n=read();m=read();
  117. S=;T=*n+;
  118. for(i=;i<=n;i++)
  119. scanf("%s",mp[i]+);
  120. solve();
  121. printf("%d\n",ans);
  122. return ;
  123. }

Bzoj1305 [CQOI2009]dance跳舞的更多相关文章

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

    http://www.lydsy.com/JudgeOnline/problem.php?id=1305 每个人拆为喜欢(yes)和不喜欢(no)两个点 二分答案 1.每两个人之间只能跳一次 喜欢则 ...

  2. BZOJ1305 [CQOI2009]dance跳舞 【网络流】

    1305: [CQOI2009]dance跳舞 Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 3714  Solved: 1572 [Submit][ ...

  3. bzoj1305: [CQOI2009]dance跳舞(二分答案+网络流)

    1305: [CQOI2009]dance跳舞 题目:传送门 题解: 一眼网络流基础建模...然后就GG了 二分答案+拆点建边+最大流判断: 把男女生拆为男1,男2,女1,女2 1.男1和男2还有女1 ...

  4. 【二分答案】【最大流】bzoj1305 [CQOI2009]dance跳舞

    http://hzwer.com/1986.html #include<cstdio> #include<algorithm> #include<queue> #i ...

  5. 并不对劲的bzoj1305: [CQOI2009]dance跳舞

    传送门-> 又是陈年老坑. 听上去不知道从何下[手]?那要是把题目换成“判断这些人能否条x支舞”呢? 这样就变成了一个网络流可以解决的问题,只要把每个人拆成喜欢和不喜欢两点,每个人两点总流量不超 ...

  6. BZOJ 1305: [CQOI2009]dance跳舞 二分+最大流

    1305: [CQOI2009]dance跳舞 Description 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞.每个男孩都不会和同一个女孩跳两首(或更多)舞曲 ...

  7. BZOJ 1305: [CQOI2009]dance跳舞( 最大流 )

    云神代码很短...0 ms过的...看了代码 , 大概是贪心... orz 我不会证 数据这么小乱搞就可以了吧... ←_← 这道题网络流还是可以写的... 既然限制了最多只能和 k 个不喜欢的人da ...

  8. AC日记——[CQOI2009]DANCE跳舞 洛谷 P3153

    [CQOI2009]DANCE跳舞 思路: 二分+最大流: 代码: #include <cstdio> #include <cstring> #include <iost ...

  9. bzoj 1305: [CQOI2009]dance跳舞

    题目链接 bzoj 1305: [CQOI2009]dance跳舞 题解 男,女生拆点A1A2,B1B2,拆成两点间分别连容量为K的边,限制与不喜欢的人跳舞的数量 A1连接源点容量为x,B1连接汇点容 ...

随机推荐

  1. spider 配置文件参考

    spider有一个配置文件spider.xml,为xml格式,spider.xml采用DTD进行管理,用于管理spider的所有特性.路由.高可用等. 配置文件支持三种不同的方式进行指定: 1. 通过 ...

  2. JavaScript--面向对象--猜拳游戏

    //html代码 <!doctype html> <html> <head> <meta charset="UTF-8"> < ...

  3. SDK接入(2)之Android Google Play内支付(in-app Billing)接入

    SDK接入(2)之Android Google Play内支付(in-app Billing)接入 继上篇SDK接入(1)之Android Facebook SDK接入整理完Facebook接入流程之 ...

  4. 完全删除TFS2013上的项目

    必备条件:您必须是 Team Foundation Server Administrators 组的成员或待删除项目的 Project Administrators 组的成员. 解决方法:打开&quo ...

  5. c#下volatile关键字

      volatile多用于多线程的环境,当一个变量定义为volatile时,读取这个变量的值时候每次都是从momery里面读取而不是从cache读.这样做是为了保证读取该变量的信息都是最新的,而无论其 ...

  6. JAVA并发编程J.U.C学习总结

    前言 学习了一段时间J.U.C,打算做个小结,个人感觉总结还是非常重要,要不然总感觉知识点零零散散的. 有错误也欢迎指正,大家共同进步: 另外,转载请注明链接,写篇文章不容易啊,http://www. ...

  7. Jdk与Tomcat配置与安装

    一.jdk的安装与配置 先下载Tomcat与jdk的压缩包:在usr/local/src目录下下载,下载方法:wget+链接 (tar.gz) 解压tomcat与jdk的压缩包: tar –zvxf ...

  8. 浅谈Virtual Machine Manager(SCVMM 2012) cluster 过载状态检测算法

    在我们使用scvmm2012的时候,经常会看到群集状态变成了这样 点开看属性后,我们发现是这样 . 发现了吗?Over-committed,如果翻译过来就是资源过载,或者说资源过量使用了,那么这个状态 ...

  9. PHP核心技术与最佳实践——全局浏览

    难得买到并喜欢一本好书,‘PHP核心技术与最佳实践’. 几天时间,先看了个大概,总结一下整体是什么样子的,怎么看怎么学. 1.总共14章: 2.第1.2章讲PHP的OOP: 其中第一章侧重于PHP的O ...

  10. float4与half4数据类型

    连续4个32位float类型数的向量 HLSL数据类型 GPU是以四维向量为基本单位来计算的.4个浮点数所组成的float4向量是GPU内置的最基本类型.使用GPU对两个float4向量进行计算,与C ...