[poj3692][匈牙利算法]

来源:互联网 发布:rf仿真软件 编辑:程序博客网 时间:2024/05/13 07:20

题意:给G个女孩和B个男孩的关系,要选出一个最大集合,集合中两两都认识。注意数据范围是男女各两百,所以点有400.。。

建反图,那么求出的子集就需要两两都不认识,从而等价于求最大独立集的大小。根据定理|最大独立集合|+|最小顶点覆盖|=|V|,又可转化为求最小顶点覆盖,从而求出完美匹配数即可,用匈牙利算法~顺便给自己留个板子

代码

#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;const int MAX = 512;bool vis[MAX];int match[MAX];int G[MAX][MAX];bool dfs(int u, int n) {for (int i = 1; i <= n; ++i) {if (!vis[i] && G[u][i]) {vis[i] = true;if (match[i] == -1 || dfs(match[i], n)) {match[i] = u;return true;}}}return false;}inline int read() {char ch;while ((ch = getchar()) < '0' || ch > '9');int x = ch - '0';while ((ch = getchar()) >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + ch - '0';}return x;}int main() {int Girl, Boy, Met;while (~scanf(" %d %d %d", &Girl, &Boy, &Met)) {if (Girl == 0 && Boy == 0 && Met == 0) break;int n = Girl + Boy;for (int i = 1; i <= n; ++i) {for (int j = 1; j <= n; ++j) {G[i][j] = 1;}}int u, v;while (Met--) {u = read();v = read();G[u][v] = 0;}memset(match, -1, sizeof(match));int tot = 0;for (int i = 1; i <= Girl; ++i) {memset(vis, false, sizeof(vis));if (dfs(i, Boy)) {++tot;//printf("%d\n", i);}}static int cas = 0;printf("Case %d: %d\n", ++cas, n - tot);}return 0;}


0 0
原创粉丝点击