[ZJOI2009]假期的宿舍

一眼二分图,匈牙利上。

/**
 * Problem:Holiday
 * Author:Shun Yao
 * Time:2013.5.31
 * Result:Accepted
 * Memo:matching
 */

#include <cstring>
#include <cstdio>
#include <cmath>

const long Maxt = 55, Maxm = 2505;

long n, wt, used[Maxt];
char vis[Maxt], a[Maxt], c[Maxt];

long tot;
class gnode {
public:
	long v;
	gnode *next;
	gnode() {}
	~gnode() {}
	gnode(long V, gnode *ne):v(V), next(ne) {}
} *g[Maxt], G[Maxm];

void add(long x, long y) {
	g[x] = &(G[tot++] = gnode(y, g[x]));
}

char dfs(long x) {
	for (gnode *e = g[x]; e; e = e->next) if (!vis[e->v]) {
		vis[e->v] = 1;
		if (!used[e->v] || dfs(used[e->v])) {
			used[e->v] = x;
			return 1;
		}
	}
	return 0;
}

int main() {
	static long T, i, j, b;
	freopen("holiday.in", "r", stdin);
	freopen("holiday.out", "w", stdout);
	scanf("%ld", &T);
	while (T--) {
		scanf("%ld", &n);
		for (i = 1; i <= n; ++i)
			g[i] = 0;
		for (i = 1; i <= n; ++i)
			scanf("%ld", a + i);
		wt = 0;
		for (i = 1; i <= n; ++i) {
			scanf("%ld", &b);
			if (!a[i] || !b) {
				c[i] = 1;
				++wt;
			} else
				c[i] = 0;
		}
		tot = 0;
		for (i = 1; i <= n; ++i) {
			for (j = 1; j <= n; ++j) {
				scanf("%ld", &b);
				if (c[i] && a[j] && (i == j || b))
					add(i, j);
			}
		}
		memset(used, 0, sizeof used);
		for (i = 1; i <= n; ++i) if (c[i]) {
			memset(vis, 0, sizeof vis);
			if (dfs(i))
				--wt;
		}
		if (!wt)
			puts("^_^");
		else
			puts("T_T");
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}
原文地址:https://www.cnblogs.com/hsuppr/p/3115473.html