注意增广路的概念:匹配的点相连的路放入集合s,遍历未匹配的点(左集合),找一个与他相邻的点(右集合),若那个点也未匹配,则找到了增广路的终点。否则找那个对应的左集合里的点,然后走一条不属于s的路,循环直到找到一个右集合中未匹配的点为止,则从起点到终点为一条增广路。相当于走(不属于s的路-》属于-》不属于)这样一条交错路。最后将这条路与之前路的异或(取消相同的路),得到的一个新的s,这时匹配的数量会加一。(因为这样其他已匹配的点可以换到匹配其他点去。可以让出来一个点给新来的要匹配的那个点)


#include<iostream>#include<queue>using namespace std;const int MAXN=500;// 最大点数const int INF=1<<28;// 距离初始值int bmap[MAXN][MAXN];//二分图int cx[MAXN];//cx[i]表示左集合i顶点所匹配的右集合的顶点序号int cy[MAXN]; //cy[i]表示右集合i顶点所匹配的左集合的顶点序号int nx,ny;int dx[MAXN];int dy[MAXN];int dis;bool bmask[MAXN];//寻找 增广路径集bool searchpath(){queue<int>Q;dis=INF;memset(dx,-1,sizeof(dx));memset(dy,-1,sizeof(dy));for(int i=1;i<=nx;i++){//cx[i]表示左集合i顶点所匹配的右集合的顶点序号if(cx[i]==-1){//将未遍历的节点 入队 并初始化次节点距离为0Q.push(i);dx[i]=0;}}//广度搜索增广路径,这样可以保证深搜时只走最短的增广路while(!Q.empty()){int u=Q.front();Q.pop();if(dx[u]>dis) break;//取右侧节点for(int v=1;v<=ny;v++){//右侧节点的增广路径的距离if(bmap[u][v]&&dy[v]==-1){dy[v]=dx[u]+1; //v对应的距离 为u对应距离加1if(cy[v]==-1) dis=dy[v];     //如果该点未被匹配,那么增广路形成,找到一个点可以使其他已匹配的点换到别的去匹配。else                         //如果该点匹配了,那么接着往下搜{dx[cy[v]]=dy[v]+1;Q.push(cy[v]);}}}}return dis!=INF;}//寻找路径 深度搜索int findpath(int u){for(int v=1;v<=ny;v++){//如果该点没有被遍历过 并且距离为上一节点+1,只有增广路上的点才会满足距上一节点距离加一的条件,且只要满足这样的条件,他俩就有可能可以匹配上if(!bmask[v]&&bmap[u][v]&&dy[v]==dx[u]+1){//对该点染色bmask[v]=1;if(cy[v]!=-1&&dy[v]==dis)   //如果该点已经被匹配了并且为最后一个匹配点,这条路也可能是增广路,但是不是最短的,因此没记录终点。深搜这条会浪费时间因此跳过{continue;}if(cy[v]==-1||findpath(cy[v]))  //如果该点未匹配或者后面的点能腾出位置,那么这就是增广路{cy[v]=u;cx[u]=v;return 1;}}}return 0;}//得到最大匹配的数目int MaxMatch(){int res=0;memset(cx,-1,sizeof(cx));memset(cy,-1,sizeof(cy));while(searchpath())    //如果存在增广路{memset(bmask,0,sizeof(bmask));for(int i=1;i<=nx;i++){if(cx[i]==-1){res+=findpath(i);}}}return res;}int main(){int num;scanf("%d",&num);while(num--){memset(bmap,0,sizeof(bmap));scanf("%d%d",&nx,&ny);for(int i=1;i<=nx;i++){int snum;scanf("%d",&snum);int u;for(int j=1;j<=snum;j++){scanf("%d",&u);bmap[i][u]=1;// bmap[u][i]=1;}}// cout<<MaxMatch()<<endl;if(MaxMatch()==nx){printf("YES\n");}else{printf("NO\n");}}//system("pause");return 0;}/*41 31 3 42*/

二分匹配Hopcroft-Carp算法相关推荐

  1. 二分匹配(匈牙利算法)

    匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最 ...

  2. 二分匹配的Hopcroft-Carp算法

    题目:HDU2063 过山车 果然Hopcroft-Carp算法快,用匈牙利算法15ms,而Hopcorft-Carp却0ms.因为匈牙利算法的时间复杂度为O(n*e),而Hopcroft-Carp算 ...

  3. 二分匹配(匈牙利算法)模板

    #include <iostream> #include <vector> using namespace std; #define MAX 1005vector< ve ...

  4. 【人工智能的数学基础】二分图与二分匹配(Bipartite Matching)

    文章目录 1. 二分图的基本概念 2. 图的匹配 3. 二分匹配与匈牙利算法 Bipartite Matching and Hungarian Algorithm. 1. 二分图的基本概念 设 G = ...

  5. 利用匈牙利算法Hopcroft-Karp算法解决二分图中的最大二分匹配问题 例poj 1469 COURSES...

    首先介绍一下题意:已知,有N个学生和P门课程,每个学生可以选0门,1门或者多门课程,要求在N个学生中选出P个学生使得这P个学生与P门课程一一对应. 这个问题既可以利用最大流算法解决也可以用匈牙利算法解 ...

  6. [ACM_图论] The Perfect Stall 完美的牛栏(匈牙利算法、最大二分匹配)

    描述 农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术.不幸的是,由于工程问题,每个牛栏都不一样.第一个星期,农夫约翰随便地让奶牛们进入牛栏,但是问题很快地显露出来:每头奶牛都只愿意在她们 ...

  7. 【HDU 2255】奔小康赚大钱 (最佳二分匹配KM算法)

    奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  8. 【网络流24题】 No.3 最小路径覆盖问题 (网络流|匈牙利算法 -最大二分匹配)...

    [题意] 给定有向图 G=(V,E).设 P 是 G 的一个简单路(顶点不相交) 的集合.如果 V 中每个 顶点恰好在 P 的一条路上,则称 P 是 G 的一个路径覆盖. P 中路径可以从 V 的任何 ...

  9. POJ - 2446 Chessboard 二分匹配+建图

    题目链接 题意很简单,是二分匹配的一种常见的题型,问题就在于怎样转换到二分图上来. 首先对对n*m-k正常点进行编号,然后遍历查找每一个正常点的上下左右是否能连接(就是判断另个点是否也是正常的),如果 ...

  10. 杭电2063--过山车(二分匹配)

    过山车 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

最新文章

  1. 数据库开发个人总结(ADO.NET小结)
  2. [Caffe]:关于Eltwise layer
  3. 【Groovy】循环控制 ( Number 注入函数实现循环 | times 函数 | upto 函数 | downto 函数 | step 函数 | 闭包作为最后参数可写在外面 )
  4. boost中bind的使用
  5. 【读书笔记】《框架设计(第2版)CLR Via C#》中两个比较有趣的知识点
  6. 格力电器:回购股份比例超3% 已耗资95.15亿元
  7. 爱奇艺回应迷雾剧场停播:以完成后期的定档官宣时间为准
  8. jdk,jre,jvm的区别以及联系
  9. Infragistics netadvantage UltraGrid (UltraWinGrid) 编程手记
  10. [转]Java游戏引擎
  11. 表格金额千分位设置及时间控件默认为空及取两位小数、获取当前日期的年份和月份
  12. linux 下ip命令对比ifconfig命令
  13. 威纶通触摸屏直接与台达变频器进行MODBUS RTU通信的具体方法(图文)
  14. python移动文件到指定文件夹
  15. layout中蛇形线和差分线的使用
  16. OSEK网络管理入门
  17. word去除各种下划线
  18. 汽车零部件开发的流程及项目管理--陈新春老师
  19. CMD命令提示符保姆级入门教程
  20. 中国知网(cnki)上caj格式转pdf的方法

热门文章

  1. 2014年总结和2015年计划
  2. Day 4 R基础概念——向量、矩阵
  3. k8s.gcr.io的镜像无法下载的问题
  4. CTC5610-VPLS开发
  5. Fllutter TabBar中文文字抖动完美解决方案
  6. 网络爬虫的“盗亦有道”
  7. 第7章 CustomView绘图进阶
  8. 计算机解题的过程实际上是实施某种算法,计算机等级考试二级C考点.doc
  9. 《HelloGitHub》第 74 期
  10. 在excel中如何筛选重复数据_如何将Excel表中重复数据筛选出来?