一眼二分图,匈牙利上。
/** * 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; }