[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;

}

 

你可能感兴趣的:([ZJOI2009]假期的宿舍)