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;
}
posted @ 2018-02-05 09:44  aziint  阅读(65)  评论(0编辑  收藏
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.