uva 1459 - Flowers Placement(二分图匹配+暴力)

题目链接:uva 1459 - Flowers Placement


暴力,在暴力的基础上用二分图匹配剪枝,如果当前位置放k,导致后面的位置不能匹配,即可回溯。


#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;
const int maxn = 205;

int N, M, K, cnt, L[maxn], vis[maxn][maxn], ans[maxn];
bool T[maxn], used[maxn];
vector<int> G[maxn];

bool match (int u, int e) {
	if (u <= e) return false;

	for (int i = 0; i < G[u].size(); i++) {
		int v = G[u][i];
		if (!T[v]) {
			T[v] = true;
			if (!L[v] || match(L[v], e)) {
				L[v] = u;
				return true;
			}
		}
	}
	return false;
}

int KM () {
	int ret = 0;
	memset(L, 0, sizeof(L));
	for (int i = 1; i <= N; i++) {
		memset(T, false, sizeof(T));
		if (match(i, 0)) ret++;
	}
	return ret;
}

void init () {
	memset(vis, 0, sizeof(vis));
	scanf("%d%d%d", &N, &M, &K);

	int x;
	for (int i = 1; i <= M; i++) {
		for (int j = 1; j <= N; j++) {
			scanf("%d", &x);
			vis[j][x] = 1;
		}
	}
	for (int i = 1; i <= N; i++) {
		G[i].clear();
		for (int j = 1; j <= N; j++) if (!vis[i][j])
			G[i].push_back(j);
	}
}

int tmp[maxn];
bool judge (int d, int c) {
	if (L[c] == d) return true;

	
	int t = 1;
	for (int i = 1; i <= N; i++) {
		tmp[i] = L[i];
		T[i] = false;
		if (L[i] == d) t = i;
	}

	int nf = L[c];
	L[c] = d;
	L[t] = 0;

	if (match(nf, d)) {
		return true;
	} else {
		memcpy(L, tmp, sizeof(int) * (N+1));
		return false;
	}
}

bool dfs (int d) {
	if (d == N + 1)
		return ++cnt == K;

	for (int i = 0; i < G[d].size(); i++) {
		int c = G[d][i];
		if (used[c]) continue;

		if (judge(d, c)) {
			used[c] = true;
			ans[d] = c;
			if (dfs(d + 1)) return true;
			used[c] = false;
		}
	}
	return false;
}

void solve () {
	cnt = 0;
	memset(used, 0, sizeof(used));

	if (KM() == N && dfs(1)) {
		for (int i = 1; i <= N; i++) printf(" %d", ans[i]);
		printf("\n");
	} else
		printf(" -1\n");
}

int main () {
	int cas;
	scanf("%d", &cas);
	for (int kcas = 1; kcas <= cas; kcas++) {
		init();
		printf("Case #%d:", kcas);
		solve();
	}
	return 0;
}


你可能感兴趣的:(uva 1459 - Flowers Placement(二分图匹配+暴力))