Maximum bipartite graph matching (Hungary)

HDU2063

Maximum matching of the bipartite graph: Maximum number of edges matches

Subject description:

RPG girls today and we went to the playground to play, finally able to get on a roller coaster dream. However, the roller coaster of each row of only two seats, but also the unwritten rule is that every girl must find a partner and her boys to do the same sitting. However, each girl has their own ideas, for example the, Rabbit and XHD only willing to do or PQK partner, Grass and linle only willing to do or LL partner, PrincessSnow willing to do the waters of the prodigal son or pseudo Queer partner. Taking into account the financial implications, boss Liu decided to just let people find a partner to sit roller coaster, other people, hey, I stood below watching. Smart Acmer, you can help calculate a maximum number of combinations you can get on a roller coaster?

Enter a description:

The first line of input data is three integer K, M, N, respectively, the number of the possible number of combinations, the number of girls, boys. 0 <K <= 1000
. 1 <= N, and M <= 500. The next K rows, each row has two numbers, respectively, male and female Ai Bj willingness to do partner. 0 end of the last input.

Output Description:

For each test, output an integer representing the number of combinations can sit up roller coaster.

Bipartite graph matching bare problematic because boys and girls number may be repeated (for men and women are different thing), built FIG when separating the male and female students into different points, if the female m individuals, male number is the basis of the original plus m, i.e. new number a + m, and that the Hungarian

Hungarian algorithm to explain

Code:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int head[N * 2], nex[N * 2], to[N * 2], match[N];
int cnt;
bool vis[N];
void pre_work() {
	cnt = 0;
	memset(head, -1, sizeof head);
	memset(nex, -1, sizeof nex);
	memset(match, -1, sizeof match);
	memset(vis, false, sizeof vis);
}
void add(int a, int b) {
	++cnt;
	to[cnt] = b;
	nex[cnt] = head[a];
	head[a] = cnt;
}
bool dfs(int p) {
	for (int i = head[p]; i != -1; i = nex[i]) {
		int y = to[i];
		if (!vis[y]) {
			vis[y] = true;
			if (match[y] == -1 || dfs(match[y])) {
				match[y] = p;
				return true;
			}
		}
	}
	return false;
}
int main()
{
	ios::sync_with_stdio(0);
	int n, m, k;
	while (cin >> k && k) {
		cin >> m >> n;
		pre_work();
		for (int i = 0; i < k; i++) {
			int a, b;
			cin >> a >> b;
			add(a, b + m);
			add(b + m, a);
		}
		int res = 0;
		for (int i = 1; i <= m; i++) {
			memset(vis, false, sizeof vis);
			if (dfs(i))++res;
		}
		cout << res << "\n";
	}
	return 0;
}

 

Published 143 original articles · won praise 11 · views 8196

Guess you like

Origin blog.csdn.net/weixin_43701790/article/details/103756436