题意
传送门 POJ 1486
题解
求幻灯片与数字的唯一匹配,考虑到合理性,每个数字至少可以配对 个幻灯片,此时是完美匹配。枚举删除边,若匹配唯一,则删除某条边后最大匹配数减少 ;反之,最大匹配数不变。
#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;
}