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

来源:互联网 发布:qq好友提取软件 编辑:程序博客网 时间:2024/06/05 02:32

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[N];vector<int> g[N];int left[N], right[N], S[N], T[N], 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[N];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;}


0 0