您的位置:首页 > 其它

POJ 1486 Sorting Slides(二分图必须边)

2014-10-29 22:27 441 查看


POJ 1486 Sorting Slides

题目链接

题意:给定一些矩形和一些点,问每个点是否能标识一个矩形(某个点在矩形内就是标识该矩形,每个矩形只能有一个标记点)

思路:二分图匹配之后,枚举匹配边,删除后在进行匹配,如果最大匹配数减少,说明这条边是唯一的匹配边,也就是该点一定对应该矩形,输出即可

代码:

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 105;

int n;

struct Point {
int x, y;
void read() {
scanf("%d%d", &x, &y);
}
} p;

struct Rec {
int x1, y1, x2, y2;
void read() {
scanf("%d%d%d%d", &x1, &x2, &y1, &y2);
}
bool in(Point p) {
return (p.x >= x1 && p.x <= x2 && p.y >= y1 && p.y <= y2);
}
} rec
;

vector<int> g
;

int left
, right
, S
, T
, bidu, bidv;

bool dfs(int u) {
S[u] = 1;
for (int i = 0; i < g[u].size(); i++) {
int v = g[u][i];
if (bidu == u && bidv == v) continue;
if (T[v]) continue;
T[v] = 1;
if (left[v] == -1 || dfs(left[v])) {
left[v] = u;
right[u] = v;
return true;
}
}
return false;
}

int hungray() {
int ans = 0;
memset(left, -1, sizeof(left));
memset(right, -1, sizeof(right));
for (int i = 0; i < n; i++) {
memset(S, 0, sizeof(S));
memset(T, 0, sizeof(T));
if (dfs(i)) ans++;
}
return ans;
}

int Max, save
;

void print() {
int bo = 0, flag = 1;
for (int i = 0; i < n; i++) save[i] = right[i];
for (int i = 0; i < n; i++) {
if (save[i] == -1) continue;
bidu = i; bidv = save[i];
if (hungray() != Max) {
if (bo) printf(" ");
else bo = 1;
printf("(%c,%d)", 'A' + i, save[i] + 1);
flag = 0;
}
}
if (flag) printf("none");
printf("\n");
}

int main() {
int cas = 0;
while (~scanf("%d", &n) && n) {
bidu = bidv = -1;
for (int i = 0; i < n; i++) {
g[i].clear();
rec[i].read();
}
for (int i = 0; i < n; i++) {
p.read();
for (int j = 0; j < n; j++) {
if (rec[j].in(p))
g[j].push_back(i);
}
}
printf("Heap %d\n", ++cas);
Max = hungray();
print();
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: