二分匹配匈牙利算法

struct Hungary {
	int n, m;				// 两个集合点的个数 
	int vis[maxn], link[maxn];
	vector <int> edge[maxn];
	
	void init(int n, int m)
	{
		this -> n = n;
		this -> m = m;
		memset(link, -1, sizeof(link));
		for(int i = 0;i <= n + m;i ++)	
			edge[i].clear();
	}
	void addEdge(int s, int t)
	{
		edge[s].push_back(t);
		edge[t].push_back(s);
	}
	int find(int k)
	{
	    for(int i = 0;i < edge[k].size();i ++)
	    {
	        int t = edge[k][i];
	        if(vis[t] == 0)
	        {
	            vis[t] = 1;
	            if(link[t] == -1 || find(link[t]))
	            {
	                link[t] = k;
	                return 1;
	            }
	        }
	    }
	    return 0;
	}
	int maxmatch()
	{
	    int ans = 0;
	    for(int i = 1;i <= n;i ++)
	    {
	        memset(vis, 0, sizeof(vis));
	        if(find(i)) ans ++;
	    }
	    return ans;
	}
}Match; 

附上矩阵版本

struct Hungary {
	int n, m;
	int mp[500][500];
	int link[maxn], vis[maxn];
	void init(int n, int m)
	{
		this -> n = n;
		this -> m = m;
		memset(link, -1, sizeof(link));
		memset(mp, 0, sizeof(mp));
	}
	void addEdge(int s, int t)
	{
		mp[s][t] = 1;	// 根据题目需要可以改有向或无向 
	}
	int find(int k)
	{
		for(int i = 1;i <= m;i ++)
		{
			if(mp[k][i] && vis[i] == 0)
			{
				vis[i] = 1;
				if(link[i] == -1 || find(link[i]))
				{
					link[i] = k;
					return 1;
				}
			}
		}
		return 0;
	}
	int maxmatch()
	{
		int ans = 0;
		for(int i = 1;i <= n;i ++)
		{
			memset(vis, 0, sizeof(vis));
			if(find(i)) ans ++;
		}
		return ans;
	}
	
}Match;

猜你喜欢

转载自blog.csdn.net/qq_41695941/article/details/81705140