http://poj.org/problem?id=1486 /* 幻灯片排序,有 N 个幻灯片,顺序乱了,每个幻灯片上写有 1 个数字,表示这个幻灯片的顺序。 现在不知道每张幻灯片上写的是哪个数字,但是可能可以推导出哪个数字写在哪个幻灯片上: 给出幻灯片的 4 个顶点坐标和从 1 到 N 的写在幻灯片上那个数字的坐标,求哪个幻灯片和哪个数字相对应。 直接二分最大匹配。。。。。。一边是幻灯片,一边是数字,哪个和哪个可能匹配则连一条边。 */ #include <iostream> using namespace std; int n; struct Point { int minx,maxx,miny,maxy; }p[30]; struct NODE { int x,y; }nd[30]; int map[30][30]; int mat[30],use[30]; int check(int i,int j) { if(nd[i].x>=p[j].minx && nd[i].x<=p[j].maxx && nd[i].y>=p[j].miny && nd[i].y<=p[j].maxy) return 1; return 0; } void read() { int i,j; memset(map,0,sizeof(map)); for(i=1;i<=n;i++) scanf("%d%d%d%d",&p[i].minx,&p[i].maxx,&p[i].miny,&p[i].maxy); for(i=1;i<=n;i++) scanf("%d%d",&nd[i].x,&nd[i].y); for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(check(i,j)) { map[i][j]=1; } } } } int path(int u) { int i; for(i=1;i<=n;i++) if(map[u][i]&&!use[i]) { use[i]=1; if(mat[i]==-1||path(mat[i])) { mat[i]=u; return 1; } } return 0; } void Maxmatch() { int i,ok,j; memset(mat,-1,sizeof(mat)); for(i=1;i<=n;i++) { memset(use,0,sizeof(use)); path(i); } ok=0; for(i=1;i<=n;i++) { int u=mat[i]; if(u==-1)continue; mat[i]=-1; //printf("%d/n",u); memset(use,0,sizeof(use)); map[u][i]=0; if(!path(u)) { ok++; mat[i]=u; if(ok>1) printf(" "); printf("(%c,%d)",i+'A'-1,mat[i]); } map[u][i]=1; } if(!ok) printf("none"); printf("/n/n"); } int main() { // freopen("in.txt", "r", stdin); int test=0; while(1) { scanf("%d",&n); if(n==0) break; read(); printf("Heap %d/n",++test); Maxmatch(); } }