zoukankan      html  css  js  c++  java
  • [笔记]二分图最大匹配--匈牙利算法

    [笔记]二分图最大匹配--匈牙利算法

    原题链

    算法:

    0.首先有一些概念:

    ​ ①.二分图:设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。(我并没有看懂上面这一坨,我的理解是可以分成两个相互独立部分的图就是二分图)

    ​ ②匹配:给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条边都不依附于同一个顶点,则称M是一个匹配。

    ​ ③:最大匹配:最大匹配即是选择其中边数最大的子集的图。

    ​ ④:增广路:若P是图G中一条连通两个未匹配顶点的路径,并且属于M的边和不属于M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广路径(举例来说,有A、B集合,增广路由A中一个点通向B中一个点,再由B中这个点通向A中一个点……交替进行)

    ​ 我们通过以上概念可以知道,二分图的一组匹配是最大匹配当且仅当图中不存在增广路.

    1.算法步骤

    ​ ①首先所有边都是非匹配边

    ​ ②寻找增广路,并将增广路两端的点设为已匹配的点

    ​ ③重复步骤②,知道图中不再有增广路

    2.详细过程

    ​ 具体说一说第②步:

    ​ 要想新建一条增广路需要满足一下两个条件中的任意一个:

    ​ 1.右半部分的点y自身为非匹配点

    ​ 2.右部分的点y为匹配点,但是与它相连的左部分的点x可以在右部分找到另一个点进行匹配

    AC代码

    #include <bits/stdc++.h>
    using namespace std;
    bool mapp[5200][5200],vis[5200];
    int match[5200];//记录左部分匹配的对象
    int n,m,s;
    bool dfs(int k){
    	for(int i = n + 1;i <= n + m;i++){
    		if(!vis[i] && mapp[k][i]){//两点之间有连边,同时没有被访问过
    			vis[i] = true;
    			if(!match[i] || dfs(match[i])){//满足上面说的两个条件
    				match[i] = k;
    				match[k] = i;
    				return true;
    			}
    		}
    	}
    	return false;
    }
    int main(){
    	cin>>n>>m>>s;
    	for(int i = 1;i <= s;i++){
    		int x,y;
    		cin>>x>>y;
    		if(x > n || y > m)continue;
    		y += n;//处理一下,因为题中给的左右部分的编号相同,不方便标记是否访问过
    		mapp[x][y] = mapp[y][x] = true;
    	}
    	int ans = 0;
    	for(int i = 1;i <= n;i++){
    		memset(vis,false,sizeof(vis));
    		for(int j = 1;j <= n;j++)//默认从左部分向右部分匹配,因此将左部分默认成已访问过
    			vis[j] = true;
    		if(dfs(i))ans++;
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    

    结束

  • 相关阅读:
    Announcement follows closure of QEDIT’s investment round with USD 10 million secured from investors
    Zero-Knowledge taxation on Ethereum
    盘点那些年被甲骨文前CEO埃里森炮轰过的厂商
    怎样才能用手机控制电脑呢?
    怎样才能用手机控制电脑呢?
    怎样才能用手机控制电脑呢?
    怎样才能用手机控制电脑呢?
    关于我写博客的那些事
    关于我写博客的那些事
    关于我写博客的那些事
  • 原文地址:https://www.cnblogs.com/czy--blog/p/13546301.html
Copyright © 2011-2022 走看看