Sorting Slides
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 4469   Accepted: 1766

Description

Professor Clumsey is going to give an important talk this afternoon. Unfortunately, he is not a very tidy person and has put all his transparencies on one big heap. Before giving the talk, he has to sort the slides. Being a kind of minimalist, he wants to do this with the minimum amount of work possible.

The situation is like this. The slides all have numbers written on them according to their order in the talk. Since the slides lie on each other and are transparent, one cannot see on which slide each number is written. 

Well, one cannot see on which slide a number is written, but one may deduce which numbers are written on which slides. If we label the slides which characters A, B, C, ... as in the figure above, it is obvious that D has number 3, B has number 1, C number 2 and A number 4.

Your task, should you choose to accept it, is to write a program that automates this process.

Input

The input consists of several heap descriptions. Each heap descriptions starts with a line containing a single integer n, the number of slides in the heap. The following n lines contain four integers xmin, xmax, ymin and ymax, each, the bounding coordinates of the slides. The slides will be labeled as A, B, C, ... in the order of the input.

This is followed by n lines containing two integers each, the x- and y-coordinates of the n numbers printed on the slides. The first coordinate pair will be for number 1, the next pair for 2, etc. No number will lie on a slide boundary.

The input is terminated by a heap description starting with n = 0, which should not be processed.

Output

For each heap description in the input first output its number. Then print a series of all the slides whose numbers can be uniquely determined from the input. Order the pairs by their letter identifier.

If no matchings can be determined from the input, just print the word none on a line by itself.

Output a blank line after each test case.

Sample Input

4
6 22 10 20
4 18 6 16
8 20 2 18
10 24 4 8
9 15
19 17
11 7
21 11
2
0 2 0 2
0 2 0 2
1 1
1 1
0

Sample Output

Heap 1
(A,4) (B,1) (C,2) (D,3) Heap 2
none 题意:有n张幻灯片重叠在了一起,并且每张幻灯片上都标记了一个数字,只是重叠之后不知道相应的数字是哪张幻灯片上的,你需要判断那几张幻灯片可以确定出它们上面标记的数字。
思路:每张幻灯片抽象为一个结点,每个数字也抽象为一个结点,并且每个数字出现在了某张幻灯片的内部,幻灯片就向该数字连一条边,这样建立了匹配图,之后就是二分匹配问题。先求一次该图最大匹配,求得的匹配数设为N;
要确定出每张幻灯片a是不是对应了某个数字b,可以先把a,b对应的边从图中删除,删除后再求该图最大匹配,若最大匹配变为了N-1,说明这条边是必须边,即确定了a,b的对应关系;反之,这条边删除后,a还可以和其他的数字对应,b还可和其他幻灯片对应,那么关系就不唯一了,无法确定。操作完成,把这条边再加进图中
把所有边都删除一次,即可确定哪些边是必须的。
AC代码:
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<algorithm>
#include<queue>
#include<set>
#include<vector>
#include<cstring>
#include<string>
using namespace std;
#define INF 0x3f3f3f3f
const int N_MAX =;
int V;//点的个数
vector<int>G[N_MAX];
int match[N_MAX];
bool used[N_MAX];
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 = ; i < G[v].size(); i++) {
int u = G[v][i], w = match[u];
if (w < || !used[w] && dfs(w)) {
match[v] = u;
match[u] = v;
return true;
}
}
return false;
} int bipartite_matching() {
int res = ;
memset(match, -, sizeof(match));
for (int v = ; v < V; v++) {
if (match[v] < ) {
memset(used, , sizeof(used));
if (dfs(v))
res++;
}
}
return res;
} struct Area {
int x_min, x_max, y_min, y_max; }area[N_MAX];
struct Cor {
int x, y;
}cor[N_MAX];
int n,s,t,COr[N_MAX];
char ARea[N_MAX];
int main() {
int Case = ;
while (scanf("%d",&n)&&n) {
Case++;
//0~n-1:区域
//n~2n-1:记号
V = * n;
for (int i = ; i < n; i++)
scanf("%d%d%d%d",&area[i].x_min,&area[i].x_max,&area[i].y_min,&area[i].y_max);
for (int i = ; i < n;i++) {
scanf("%d%d",&cor[i].x,&cor[i].y);
for (int j = ; j < n;j++) {
if (area[j].x_min<cor[i].x&&area[j].x_max>cor[i].x&&area[j].y_min<cor[i].y&&area[j].y_max>cor[i].y)
add_edge(j, i + n);
}
}
int N = bipartite_matching();//一开始匹配数
int num = ;
for (int i = ; i < n;i++) {//对于每一块区域
for (int j = ; j < n;j++) {//对于每一个坐标点
if (area[i].x_min<cor[j].x&&area[i].x_max>cor[j].x&&area[i].y_min<cor[j].y&&area[i].y_max>cor[j].y) {
vector<int>::iterator it1 = find(G[i].begin(),G[i].end(),j+n);
vector<int>::iterator it2 = find(G[j + n].begin(), G[j + n].end(), i);
G[i].erase(it1);
G[j + n].erase(it2);
if (bipartite_matching() < N) {//说明是必须边
ARea[num] = i+;
COr[num] = j+;
num++;
}
add_edge(i, j + n);//复原
}
}
} if (!num)printf("Heap %d\nnone\n",Case);
else {
printf("Heap %d\n", Case);
for (int i = ; i < num;i++) {
printf("(%c,%d) ",ARea[i],COr[i]);
}
puts("");
}
puts("");
for (int i = ; i < V;i++) {
G[i].clear();
}
}
return ;
}

poj 1486 Sorting Slides的更多相关文章

  1. POJ 1486 Sorting Slides (KM)

    Sorting Slides Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2831   Accepted: 1076 De ...

  2. POJ 1486 Sorting Slides(二分图匹配)

    [题目链接] http://poj.org/problem?id=1486 [题目大意] 给出每张幻灯片的上下左右坐标,每张幻灯片的页码一定标在这张幻灯片上, 现在问你有没有办法唯一鉴别出一些幻灯片 ...

  3. poj 1486 Sorting Slides(二分图匹配的查找应用)

    Description Professor Clumsey is going to give an important talk this afternoon. Unfortunately, he i ...

  4. POJ 1486 Sorting Slides(寻找必须边)

    题意:找出幻灯片与编号唯一对应的情况 思路: 1:求最大匹配,若小于n,则答案为none,否则转2 (不过我代码没有事先判断一开始的最大匹配数是否<n,但这样也过了,估计给的数据最大匹配数一定为 ...

  5. POJ 1486 Sorting Slides (二分图关键匹配边)

    题意 给你n个幻灯片,每个幻灯片有个数字编号1~n,现在给每个幻灯片用A~Z进行编号,在该幻灯片范围内的数字都可能是该幻灯片的数字编号.问有多少个幻灯片的数字和字母确定的. 思路 确定幻灯片的数字就是 ...

  6. POJ 1486 Sorting Slides(二分图完全匹配必须边)题解

    题意:给你n张照片的范围,n个点的坐标,问你能唯一确定那几个点属于那几张照片,例如样例中4唯一属于A,2唯一属于C,1唯一属于B,3唯一属于C 思路:进行二分图完全匹配,怎么判断唯一属于?匹配完之后删 ...

  7. POJ 1486 Sorting Slides【二分图匹配】

    题目大意:有n张幻灯片和n个数字,幻灯片放置有重叠,每个数字隶属于一个幻灯片,现在问你能够确定多少数字一定属于某个幻灯片 思路:上次刷过二分图的必须点后这题思路就显然了 做一次二分匹配后将当前匹配的边 ...

  8. 【POJ】1486:Sorting Slides【二分图关键边判定】

    Sorting Slides Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5390   Accepted: 2095 De ...

  9. ACM: poj 1094 Sorting It All Out - 拓扑排序

    poj 1094 Sorting It All Out Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%lld & ...

随机推荐

  1. sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) Cannot add a NOT NULL column with default value NULL [SQL: u'ALTER TABLE address_scopes ADD COLUMN ip_version INTEGER NOT NULL']

    root@hett-virtual-machine:~# su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neu ...

  2. SVN中的check out与export的区别

    http://blog.csdn.net/zndxlxm/article/details/7763116 check out跟check in对应,export跟import对应. check out ...

  3. 解决因为手机设置字体大小导致h5页面在webview中变形的BUG

    首先,我们做了一个H5页面,在各种手机浏览器中打开都没问题.我们采用了rem单位进行布局,通过JS来动态计算网页的视窗宽度,动态设置html的font-size,一切都比较完美. 这时候,你自信满满的 ...

  4. 解决IIS7多域名绑定同一物理目录,设置不同的默认文档的问题

    IIS7多域名绑定同一物理目录,设置不同的默认文档是没办法设置的,因为在一个物理目录下只有一个web.config,并且IIS7把默认文档设置写在这里,导致所有域名的默认文档设置共享.解决方法:1.进 ...

  5. Bootstrap 默认/标准按钮

    Bootstrap 默认/标准按钮 <!DOCTYPE html><html><head><meta http-equiv="Content-Typ ...

  6. 拖拽大图轮播pc 移动兼容

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  7. 洛谷 P1214 等差数列

    https://www.luogu.org/problemnew/show/P1214 首先暴力枚举可以凑出来的数,对于每个数进行标记. 对于每一个等差数列,当我们知道前两个数后即可以得出整个序列,那 ...

  8. 【二分】bestcoder p1m2

    模型的转化和二分check的细节挺不错的 Problem Description 度度熊很喜欢数组!! 我们称一个整数数组为稳定的,若且唯若其同时符合以下两个条件: 数组里面的元素都是非负整数. 数组 ...

  9. break、continue、exit、return的区别和对比

    break.continue.exit.return的区别和对比 一:说明 break.continue在条件循环语句及循环语句(for.while.if等)中用于控制程序的走向:而exit则用于种植 ...

  10. ASP.NET使用Memcached高缓存实例的初级介绍

    Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态.数据库驱动网站的速度.Memcached ...