POJ 1486 maximum binary match + enumeration

Title

Portal POJ 1486

answer

Seek unique matching of slides and numbers, considering the rationality, each number can be matched at least 1 1 slide, this time is a perfect match. Enumerate delete edges. If the match is unique, the maximum number of matches decreases after deleting an edge 1 1 ; otherwise, the maximum number of matches remains unchanged.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#define min(a,b)    (((a) < (b)) ? (a) : (b))
#define max(a,b)    (((a) > (b)) ? (a) : (b))
#define abs(x)    ((x) < 0 ? -(x) : (x))
#define INF 0x3f3f3f3f
#define delta 0.85
#define eps 1e-10
#define PI 3.14159265358979323846
using namespace std;

#define MAX_V 55
int V;
vector<int> G[MAX_V];
int match[MAX_V];
bool used[MAX_V];

void add_edge(int u, int v){
	G[u].push_back(v);
	G[v].push_back(u);
}

bool dfs(int v){
	used[v] = true;
	for(int i = 0; i < G[v].size(); i++){
		int u = G[v][i], w = match[u];
		if(w < 0 || (!used[w] && dfs(w))){
			match[v] = u;
			match[u] = v;
			return true;
		}
	}
	return false;
}

int bipartite_matching(){
	int res = 0;
	memset(match, -1, sizeof(match));
	for(int v = 0; v < V; v++){
		if(match[v] < 0){
			memset(used, 0, sizeof(used));
			if(dfs(v)){
				++res;
			}
		}
	}
	return res;
}


#define MAX_N 26
int N;
int pX[MAX_N], pY[MAX_N];
int minX[MAX_N], maxX[MAX_N], minY[MAX_N], maxY[MAX_N];

typedef pair<int, int> P; // point, slide
P pr[MAX_N * MAX_N];
P res[MAX_N];

bool judge(int i, int j){
	return pX[i] <= maxX[j] && pX[i] >= minX[j] && pY[i] <= maxY[j] && pY[i] >= minY[j];
}

void clear_graph(){
	for(int v = 0; v < V; v++) G[v].clear();
}

void solve(){
	// 求幻灯片与数字的可能配对
	int cnt = 0;
	for(int i = 0; i < N; i++){
		for(int j = 0; j < N; j++){
			if(judge(i, j)) pr[cnt++] = P(i, N + j);
		}
	}
	// 求最大流
	V = N + N;
	clear_graph();
	for(int i = 0; i < cnt; i++) add_edge(pr[i].first, pr[i].second);
	int n = 0, f = bipartite_matching();
	// 枚举删边求解
	for(int i = 0; i < cnt; i++){
		clear_graph();
		for(int j = 0; j < cnt; j++){
			if(i == j) continue;
			add_edge(pr[j].first, pr[j].second);
		}
		if(bipartite_matching() == f - 1) res[n++] = P(pr[i].second - N, pr[i].first);
	}
	// 不存在可唯一匹配对
	if(n == 0){
		printf("none\n");
		return;
	}
	// 幻灯片字典序输出
	sort(res, res + n);
	for(int i = 0; i < n; i++){
		printf("(%c,%d)%c", res[i].first + 'A', res[i].second + 1, i + 1 == n ? '\n' : ' ');
	}
}

int main(){
	int t = 0;
	while(~scanf("%d", &N) && N){
		for(int i = 0; i < N; i++) scanf("%d%d%d%d", minX + i, maxX + i, minY + i, maxY + i);
		for(int i = 0; i < N; i++) scanf("%d%d", pX + i, pY + i);
		printf("Heap %d\n", ++t);
		solve();
		putchar('\n');
	}
	return 0;
}
Published 110 original articles · Like1 · Visitors 2041

Guess you like

Origin blog.csdn.net/neweryyy/article/details/105544954