bzoj1433 [ZJOI2009]假期的宿舍
Description & Input
Output
Sample Input
1
3
1 1 0
0 1 0
0 1 1
1 0 0
1 0 0
Sample Output
ˆ_ˆ
Solution
匈牙利裸题,用来练手。人和床之间连边。注意连边条件,见代码。
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 51
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define drp(i, a, b) for (int i = a; i >= b; i--)
#define fech(i, x) for (int i = 0; i < x.size(); i++)
#define ll long long
inline int read() {
int x = 0, flag = 1; char ch = getchar();
while (ch > '9' || ch < '0') { if (ch == '-') flag = -1; ch = getchar(); }
while (ch <= '9' && ch >= '0') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * flag;
}
inline void write(int x) { if (x >= 10) write(x / 10); putchar(x % 10 + '0'); }
int n;
vector<int> g[N];
bool sch[N], bak[N];
int state[N], result[N], stt;
void init() {
stt = 0;
memset(sch, 0, sizeof sch);
memset(bak, 0, sizeof bak);
memset(state, 0, sizeof state);
memset(result, 0, sizeof result);
rep(i, 1, n) g[i].clear();
}
bool gou(int u) {
fech(i, g[u]) {
int v = g[u][i];
if (state[v] == stt) continue;
state[v] = stt;
if (!result[v] || gou(result[v])) { result[v] = u; return true; }
}
return false;
}
int main() {
int T = read();
while (T--) {
n = read(); int ans = 0, tot = n;
init();
rep(i, 1, n) sch[i] = read();
rep(i, 1, n) {
bak[i] = read();
if (sch[i])
if (bak[i]) tot--;
else g[i].push_back(i);
else bak[i] = 0;
}
rep(i, 1, n) rep(j, 1, n) if (read()) {
if (sch[j] && !bak[i]) g[i].push_back(j);
if (sch[i] && !bak[j]) g[j].push_back(i);
}
rep(i, 1, n) { stt++; if (gou(i)) ans++; }
puts(ans == tot ? "^_^" : "T_T");
}
return 0;
}