【BZOJ1305】跳舞(网络流)

题面

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

题解

如果这题换个问法:能不能跳a支舞曲

我们来看看

把每个人拆成喜欢和不喜欢两个点

从S向每个男生连容量为a的边,表示限制a支舞曲

再从男生连向喜欢和不喜欢的两个点,

但是这样子没法限制,因为只说了不能和超过K个不喜欢的人跳舞

所以可以直接从S连向男生喜欢,容量为a

再从男生喜欢连向男生不喜欢连边,容量为K

这样的话就解决了这个问题

接下来就很好办了

男生喜欢连向女生喜欢

男生不喜欢连向女生不喜欢

而女生之间的连边类似于男生

(你就想,如果这个图反过来是一样的,所以怎么连边就很清晰了)

这个时候跑最大流

求出来的就是最大的匹配数

如果最大流恰好等于an

也就是恰好a
n组匹配,意味着可行

现在再来看这个问题

既然要求最大的a

所以就二分一下

然后每次把图重构一下流量

二分就行了

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<algorithm>
  7. #include<set>
  8. #include<map>
  9. #include<vector>
  10. #include<queue>
  11. using namespace std;
  12. #define MAX 300
  13. #define MAXL 100000
  14. #define INF 1000000000
  15. inline int read()
  16. {
  17. int x=0,t=1;char ch=getchar();
  18. while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
  19. if(ch=='-')t=-1,ch=getchar();
  20. while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
  21. return x*t;
  22. }
  23. struct Line
  24. {
  25. int v,next,w;
  26. }e[MAXL];
  27. int h[MAX],cnt;
  28. int ans,S,T,n,m,K;
  29. inline void Add(int u,int v,int w)
  30. {
  31. e[cnt]=(Line){v,h[u],w};
  32. h[u]=cnt++;
  33. e[cnt]=(Line){u,h[v],0};
  34. h[v]=cnt++;
  35. }
  36. int level[MAX];
  37. int cur[MAX];
  38. bool BFS()
  39. {
  40. memset(level,0,sizeof(level));
  41. level[S]=1;
  42. queue<int> Q;
  43. Q.push(S);
  44. while(!Q.empty())
  45. {
  46. int u=Q.front();Q.pop();
  47. for(int i=h[u];i!=-1;i=e[i].next)
  48. {
  49. int v=e[i].v;
  50. if(e[i].w&&!level[v])
  51. level[v]=level[u]+1,Q.push(v);
  52. }
  53. }
  54. return level[T];
  55. }
  56. int DFS(int u,int flow)
  57. {
  58. if(flow==0||u==T)return flow;
  59. int ret=0;
  60. for(int &i=cur[u];i!=-1;i=e[i].next)
  61. {
  62. int v=e[i].v;
  63. if(e[i].w&&level[v]==level[u]+1)
  64. {
  65. int dd=DFS(v,min(flow,e[i].w));
  66. flow-=dd;ret+=dd;
  67. e[i].w-=dd;e[i^1].w+=dd;
  68. }
  69. }
  70. return ret;
  71. }
  72. int Dinic()
  73. {
  74. int ret=0;
  75. while(BFS())
  76. {
  77. for(int i=S;i<=T;++i)cur[i]=h[i];
  78. ret+=DFS(S,INF);
  79. }
  80. return ret;
  81. }
  82. char g[MAX][MAX];
  83. void Build(int mid)
  84. {
  85. memset(h,-1,sizeof(h));
  86. cnt=0;
  87. for(int i=1;i<=n;++i)
  88. {
  89. Add(S,i,mid);
  90. Add(i+n+n,T,mid);
  91. Add(i,i+n,K);
  92. Add(i+n+n+n,i+n+n,K);
  93. }
  94. for(int i=1;i<=n;++i)
  95. for(int j=1;j<=n;++j)
  96. if(g[i][j]=='Y')
  97. Add(i,j+n+n,1);
  98. else
  99. Add(i+n,j+n+n+n,1);
  100. }
  101. int main()
  102. {
  103. n=read();K=read();
  104. S=0;T=n+n+n+n+1;
  105. for(int i=1;i<=n;++i)
  106. scanf("%s",g[i]+1);
  107. int l=0,r=n;
  108. while(l+1<r)
  109. {
  110. int mid=(l+r)>>1;
  111. Build(mid);
  112. if(Dinic()==mid*n)l=mid;
  113. else r=mid;
  114. }
  115. Build(r);
  116. printf("%d\n",Dinic()==r*n?r:l);
  117. return 0;
  118. }

【BZOJ1305】跳舞(网络流)的更多相关文章

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

    1305: [CQOI2009]dance跳舞 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 3944  Solved: 1692[Submit][St ...

  2. [CQOI2009]跳舞 网络流

    题面:[CQOI2009]跳舞 题解: 首先最大时间不好求,而且数据范围很小,所以我们可以先二分一个最大时间,然后就只需要判断是否可行即可. 因此我们每二分一个mid,对于每个女生,连s ---> ...

  3. [bzoj1305]跳舞

    考虑如果没有k个人,那么就是裸的二分答案+最大流对于这k个人,再在原来的每一个点裂点,中间的流量为k,然后裂出来的点向所有不能匹配的点连边,再二分答案+最大流即可 1 #include<bits ...

  4. AHOI2018训练日程(3.10~4.12)

    (总计:共90题) 3.10~3.16:17题 3.17~3.23:6题 3.24~3.30:17题 3.31~4.6:21题 4.7~4.12:29题 ZJOI&&FJOI(6题) ...

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

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

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

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

  7. Bzoj1305 [CQOI2009]dance跳舞

    Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 2925  Solved: 1221 Description 一次舞会有n个男孩和n个女孩.每首曲子开始时 ...

  8. BZOJ-1305 dance跳舞 建图+最大流+二分判定

    跟随YveH的脚步又做了道网络流...%%% 1305: [CQOI2009]dance跳舞 Time Limit: 5 Sec Memory Limit: 162 MB Submit: 2119 S ...

  9. 【BZOJ1305】【CQOI2009】 dance跳舞

    看menci的博客点出二分的思路然后做出来,menci太强辣 原题: 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞.每个男孩都不会和同一个女孩跳两首(或更多)舞曲. ...

随机推荐

  1. 安装php的memcached模块和扩展支持sasl

    memcached的1.2.4及以上增加了CAS(Check and Set)协议,对于同一key的多进行程的并发处理问题.这种情况其实根数据库很像,如果同时有几个进程对同一个表的同一数据进行更新的话 ...

  2. [bzoj2286][Sdoi 2011]消耗战

    [bzoj2286]消耗战 标签: 虚树 DP 题目链接 题解 很容易找出\(O(mn)\)的做法. 只需要每次都dp一遍. 但是m和n是同阶的,所以这样肯定会T的. 注意到dp的时候有很多节点是不需 ...

  3. tpframe框架之slide模块的使用

    最新版git:https://gitee.com/37duman/tpframe 下载插件 点击下载slide插件 安装插件 把下载下来的插件解压后放置在addon文件夹 登录后台,点击插件管理 点击 ...

  4. 在Centos环境下安装兼容Apache2.4高版本SVN服务

    在阿里云Centos环境下,搭建PHP运行环境,PHP选择了php7版本,Mysql选择了5.7版本,Apache选择了2.4版本,在搭建SVN版本控制服务过程中出现了不兼容问题,当前环境下Apach ...

  5. Swagger2 Oauth2.0 令牌 请求头

    @EnableSwagger2 @Bean public Docket createRestApi() { ParameterBuilder tokenPar = new ParameterBuild ...

  6. ES6的介绍和常用语法

    本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. 前言 ECMAScript 是 JS 的语言标准.而 ES6 是新的 J ...

  7. java读取数据写入txt文件并将读取txt文件写入另外一个表

    package com.xsw.test; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.F ...

  8. java I/O框架 (二)文件操作(File)

    1.介绍 java io中最常操作的就是我们电脑中的文件,将这些文件以流的形式本地读写,或者上传到网络上.java中的File类就是对这些存储于磁盘上文件的虚拟映射,这也体现了java面向对象的思想, ...

  9. find命令 参数

    记一下我遇到过的: 中 !表示否定 -a 表示并且 -o  或者   perm注意权限模式,有无 -,单表含义不同,有-是表示属主.组.其他组权限对应(即某位为0时,表示不指定要匹配的权限,而不是没有 ...

  10. mongodb一些使用技巧或注意事项记录

    1.有的时候需要删除指定字段那一列,使用update操作.例如要删除name这一列: query  json: {"name":{$exists:true}} update jso ...