基本概念:二分图有两种节点:X节点和Y节点。如果X和Y可以匹配, 则X与Y连着一条边。每个X节点最多只能匹配一个Y节点,同时每个Y节点最多只能匹配一个X节点。最大匹配便是最多的匹配数。

交错路径:交错路径中的边分为重边和轻边。每个每两个相邻的边的种类是不同的。对于两端的边都为轻边的一条交错路径,此时如果把轻边变成重边,重边变成轻边(以后此操作简称翻转),路径上重边的数量便会多一个。

在二分图最大匹配中,一个X一个X地,看看以下通过Dfs实现的操作能否成功:把当前X节点当作起点,图中已经匹配的边为潜在的重边,去寻找一个未匹配过的Y节点。如果操作成功,将找到的交错路径一翻转,匹配的数量就多了一个。最后输出总匹配的数量即可。

注意:Dfs的Vis标记在Y里,而不在X里。

#include <cstdio>
#include <cstring>
using namespace std; const int MAX_XNODE = 1010, MAX_YNODE = 1010, MAX_EDGE = MAX_XNODE*MAX_YNODE;
#define LOOP(i, n) for(int i=1; i<=n; i++) struct Hungary
{
private:
struct Xnode;
struct Ynode;
struct Edge; struct Xnode
{
Edge *Head;
}_xNodes[MAX_XNODE];
int _xCnt; struct Ynode
{
Xnode *Match;
bool Vis;
}_yNodes[MAX_YNODE];
int _yCnt; struct Edge
{
Xnode *X;
Ynode *Y;
Edge *Next;
}*_edges[MAX_EDGE];
int _eCnt; Edge *NewEdge()
{
return _edges[++_eCnt] = new Edge();
} bool Dfs(Xnode *x)
{
for (Edge *e = x->Head; e; e = e->Next)
{
if (!e->Y->Vis)
{
e->Y->Vis = true;
if (!e->Y->Match || Dfs(e->Y->Match))
{
e->Y->Match = x;
return true;
}
}
}
return false;
} public:
Hungary(){} Hungary(int xCnt, int yCnt) :_xCnt(xCnt), _yCnt(yCnt), _eCnt(0)
{
memset(_xNodes, 0, sizeof(_xNodes));
memset(_yNodes, 0, sizeof(_yNodes));
memset(_edges, 0, sizeof(_edges));
} void AddEdge(int xId, int yId)
{
Xnode *x = _xNodes + xId;
Ynode *y = _yNodes + yId;
Edge *e = NewEdge();
e->X = x;
e->Y = y;
e->Next = x->Head;
x->Head = e;
} int GetMatchCnt()
{
int ans = 0;
LOOP(xId, _xCnt)
{
LOOP(yId, _yCnt)
_yNodes[yId].Vis = false;
ans += Dfs(_xNodes + xId);
}
return ans;
}
}; int main()
{
#ifdef _DEBUG
freopen("c:\\noi\\source\\input.txt", "r", stdin);
#endif
int totX, totY, totE, xId, yId;
scanf("%d%d%d", &totX, &totY, &totE);
static Hungary g(totX, totY);
while (totE--)
{
scanf("%d%d", &xId, &yId);
if (xId > totX || yId > totY)
continue;
g.AddEdge(xId, yId);
}
printf("%d\n", g.GetMatchCnt());
return 0;
}

  

最新文章

  1. 【OpenCV】访问图像中每个像素的值
  2. Java技巧(代码简略)
  3. iOS第三方类库JSPatch(热更新)
  4. hdu4933 Miaomiao&#39;s Function
  5. Opencv2系列学习笔记10(提取连通区域轮廓)
  6. excel 导入功能
  7. 你不需要jQuery(二)
  8. IBM即将倒闭,微软也从崩溃18个月
  9. 【c++】指针参数是如何传递内存的
  10. CentOS 7.3 minimal 开启网络服务
  11. ORACLE 数据库管理
  12. Linux启动过程简述
  13. 用pyspider爬取并解析json字符串
  14. 【Java每日一题】20170316
  15. MFC 坦克定位
  16. Python之切片操作
  17. 三元一次方程问题(for嵌套)
  18. Linux设置Oracle环境变量
  19. poj1308(并查集)
  20. 【 js 基础 】【 源码学习 】源码设计 (更新了backbone分析)

热门文章

  1. itext 生成doc文档 小结(自己备忘)
  2. .net MVC成长记录(四)Linq(1)
  3. shiro英语
  4. JavaScript 原型和引用趣点
  5. 基于 CC2530 的温度采集系统(未定稿)
  6. std::string格式化输入输出
  7. 本博客基本不再更新,请移步至我的CSDN博客
  8. js 习题
  9. 【转载】java读取.properties配置文件的几种方法
  10. VS 2017 统计项目代码总行数