• luogu3386 【模板】 二分图匹配


    基本概念:二分图有两种节点: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
    ", g.GetMatchCnt());
    	return 0;
    }
    

      

  • 相关阅读:
    python torch安装下载地址
    anaconda windows常用命令
    VBA手册
    聊聊FLINK25631贡献
    适配若依框架的字典翻译
    ROS使用catkin_make编译
    Linux_软件安装和Dockerfile
    云计算_Dockerfile与代理
    CI/CD_Git大文件问题定位和排查
    C++_标准库和第三方库
  • 原文地址:https://www.cnblogs.com/headboy2002/p/8661079.html
Copyright © 2020-2023  润新知