10566 Bimatching

  • 题意:一个男生必须跟两个女生匹配,求最大匹配

  • 思路:一般的二分图匹配做不了,网络流也不会建图,这题采用的是一般图匹配

  • 首先在原来二分图的基础上,将一个男生拆成两个点

  • 两个点之间有一条边,这样图至少会有n个匹配

  • 如果想要答案加1,只有当这两个点跟两个女生匹配的时候

  • 所以最后的答案是一般图最大匹配减去n

  • 一般图最大匹配用带花树

  1. #pragma GCC optimize(3, "Ofast", "inline")
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. const int maxn = 305;
  5. const int maxm = 50050;
  6. struct bloosom {
  7. struct edge {
  8. int to, next;
  9. } e[maxm];
  10. int tot = 0, head[maxn];
  11. inline void add(int u, int v) {
  12. ++tot;
  13. e[tot].to = v, e[tot].next = head[u], head[u] = tot;
  14. ++tot;
  15. e[tot].to = u, e[tot].next = head[v], head[v] = tot;
  16. }
  17. int fa[maxn], tag = 0, pre[maxn], match[maxn], q[maxn], r, fl[maxn];
  18. int vis[maxn], all;
  19. int findx(int x) {
  20. if (fa[x] == x)return x;
  21. return fa[x] = findx(fa[x]);
  22. }
  23. int lca(int u, int v) {
  24. ++tag;
  25. u = findx(u);
  26. v = findx(v);
  27. for (;; swap(u, v)) {
  28. if (u) {
  29. if (fl[u] == tag)return u;
  30. fl[u] = tag;
  31. u = findx(pre[match[u]]);
  32. }
  33. }
  34. }
  35. void blo(int u, int v, int l) {
  36. for (; findx(u) != l; v = match[u], u = pre[v]) {
  37. pre[u] = v;
  38. if (vis[match[u]] == 1)vis[q[++r] = match[u]] = 0;
  39. if (findx(u) == u) fa[u] = l;
  40. if (findx(match[u]) == match[u]) fa[match[u]] = l;
  41. }
  42. }
  43. bool aug(int s) {
  44. for (int j = 1; j <= all; ++j) {
  45. fa[j] = j;
  46. vis[j] = -1;
  47. }
  48. vis[q[r = 1] = s] = 0;
  49. int x, y;
  50. for (int i = 1; i <= r; ++i) {
  51. for (int j = head[x = q[i]]; j; j = e[j].next) {
  52. if (vis[y = e[j].to] == -1) {
  53. pre[y] = x;
  54. vis[y] = 1;
  55. if (!match[y]) {
  56. for (int u = x, v = y, t; u; v = t, u = pre[v]) {
  57. t = match[u];
  58. match[u] = v;
  59. match[v] = u;
  60. }
  61. return 1;
  62. }
  63. vis[q[++r] = match[y]] = 0;
  64. } else if (!vis[y] && findx(x) != findx(y)) {
  65. int l = lca(x, y);
  66. blo(x, y, l);
  67. blo(y, x, l);
  68. }
  69. }
  70. }
  71. return 0;
  72. }
  73. inline void init() {
  74. for (int i = 0; i <= all; ++i) {
  75. pre[i] = match[i] = head[i] = 0;
  76. }
  77. tot = 0;
  78. }
  79. int solve() {
  80. int ans = 0;
  81. for (int i = 1; i <= all; ++i) {
  82. if (!match[i]) {
  83. if (aug(i)) ans++;
  84. }
  85. }
  86. return ans;
  87. }
  88. } st;
  89. int main() {
  90. int _;
  91. scanf("%d", &_);
  92. while (_--) {
  93. int n, m, s;
  94. scanf("%d%d", &n, &m);
  95. st.all = n * 2 + m;
  96. st.init();
  97. for (int i = 1; i <= n; ++i) {
  98. st.add(i, i + n);
  99. for (int j = 1; j <= m; ++j) {
  100. scanf("%1d", &s);
  101. if (s) {
  102. st.add(i, j + (n << 1));
  103. st.add(i + n, j + (n << 1));
  104. }
  105. }
  106. }
  107. printf("%d\n", st.solve() - n);
  108. }
  109. return 0;
  110. }

[一般图最大匹配]Bimatching的更多相关文章

  1. UOJ79 一般图最大匹配

    题目描述 从前一个和谐的班级,所有人都是搞OI的.有 nn 个是男生,有 00 个是女生.男生编号分别为 1,-,n1,-,n. 现在老师想把他们分成若干个两人小组写动态仙人掌,一个人负责搬砖另一个人 ...

  2. [转]带花树,Edmonds's matching algorithm,一般图最大匹配

    看了两篇博客,觉得写得不错,便收藏之.. 首先是第一篇,转自某Final牛 带花树……其实这个算法很容易理解,但是实现起来非常奇葩(至少对我而言). 除了wiki和amber的程序我找到的资料看着都不 ...

  3. HDOJ 4687 Boke and Tsukkomi 一般图最大匹配带花树+暴力

    一般图最大匹配带花树+暴力: 先算最大匹配 C1 在枚举每一条边,去掉和这条边两个端点有关的边.....再跑Edmonds得到匹配C2 假设C2+2==C1则这条边再某个最大匹配中 Boke and ...

  4. 【Learning】带花树——一般图最大匹配

    一般图最大匹配--带花树 问题 ​ 给定一个图,求该图的最大匹配.即找到最多的边,使得每个点至多属于一条边. ​ 这个问题的退化版本就是二分图最大匹配. ​ 由于二分图中不存在奇环,偶环对最大匹配并无 ...

  5. HDU 4687 Boke and Tsukkomi (一般图最大匹配)【带花树】

    <题目链接> 题目大意: 给你n个点和m条边,每条边代表两点具有匹配关系,问你有多少对匹配是冗余的. 解题分析: 所谓不冗余,自然就是这对匹配关系处于最大匹配中,即该匹配关系有意义.那怎样 ...

  6. 【UOJ#79】一般图最大匹配(带花树)

    [UOJ#79]一般图最大匹配(带花树) 题面 UOJ 题解 带花树模板题 关于带花树的详细内容 #include<iostream> #include<cstdio> #in ...

  7. ZOJ 3316 Game 一般图最大匹配带花树

    一般图最大匹配带花树: 建图后,计算最大匹配数. 假设有一个联通块不是完美匹配,先手就能够走那个没被匹配到的点.后手不论怎么走,都必定走到一个被匹配的点上.先手就能够顺着这个交错路走下去,最后一定是后 ...

  8. [WC2016]挑战NPC(一般图最大匹配)

    [WC2016]挑战NPC(一般图最大匹配) Luogu 题解时间 思路十分有趣. 考虑一个筐只有不多于一个球才有1的贡献代表什么. 很明显等效于有至少两个位置没有被匹配时有1的贡献. 进而可以构造如 ...

  9. 【learning】一般图最大匹配——带花树

    问题描述 ​ 对于一个图\(G(V,E)\),当点对集\(S\)满足任意\((u,v)\in S\),均有\(u,v\in V,(u,v)\in E\),且\(S\)中没有点重复出现,我们称\(S\) ...

随机推荐

  1. 关于javascript中this 指向的4种调用模式

    this指向问题绝对可以排js 的top 5最难和最重点的问题,初学者常常搞不清楚this指向哪里,特别是学过java和c#的人,想当年俺也迷糊了好久,直到遇到蝴蝶书,主要是因为js和主流的面向对象语 ...

  2. Android群英传神兵利器读书笔记——第三章:Android Studio奇技淫巧

    这篇文章篇幅较长,可以使用版权声明下面的目录,找到感兴趣的进行阅读 3.1 Android Studio使用初探 Project面板 Stucture面板 Android Monitor Keymap ...

  3. mybatis的批量update

    方法有三种:1.通过java代码batch方式,xml文件只需一条update语句.java代码繁琐 2.xml使用foreach,“;”分割多条update语句,要求:jdbc的url需加上allo ...

  4. BUUCTF-WEB-easy_tornado

    知识点: Python Web 框架:Tornado python中的一个渲染函数:render: 渲染变量到模板中,即可以通过传递不同的参数形成不同的页面. 1. render方法的实质就是生成te ...

  5. POJ 1401:Factorial 求一个数阶乘的末尾0的个数

    Factorial Time Limit: 1500MS   Memory Limit: 65536K Total Submissions: 15137   Accepted: 9349 Descri ...

  6. 使用websocket实现单聊和多聊

    单聊: 前端: <!DOCTYPE html> <html lang="zh-CN"> <head> <meta http-equiv=& ...

  7. 合并两个word文档,保持样式不变

    一.需求说明 例如将封面插入到word正文上方 二.导入依赖 <dependency> <groupId>org.apache.poi</groupId> < ...

  8. 什么是控制反转IOC

    1.IOC 是什么 IOC- Inversion of Control , 即“控制反转” ,不是一个技术,而是一个设计思想,在java 开发中,IOC意味着将你设计好的Java 对象交个容器控制,而 ...

  9. VBA单元格自适应高亮操作

    1.单元格所在行和列高亮 第一种方式 Private Sub worksheet_selectionchange(ByVal target As Range) Cells.Interior.Color ...

  10. SpringCloud----服务注册中心Eureka

    Eureka是Netflix开源的一个RESTful服务,主要用于服务的注册发现.Eureka由两个组件组成:Eureka服务器和Eureka客户端.Eureka服务器用作服务注册服务器.Eureka ...