题意:给定N张幻灯片的maxx,minx,maxy,miny,和N个点的位置,表示幻灯片的编号,编号写在幻灯片上,问幻灯片与编号形成的最大匹配能否确定唯一的匹配,输出已确定的唯一匹配;
分析:若编号与幻灯片满足 minx<x<maxx, miny<y<maxy,则形成一个可能的匹配,求出最大匹配(肯定是完美匹配的)之后,再依次判定该匹配边是否为必须边
判定方法:先将该匹配边删除,判定从该点出发是否存在增广路径,若存在,则不是必须边,反之,为必须边;
#include<iostream> using namespace std; bool mat[26][26],vis[26]; int mx[26],my[26],n; struct slide { int xmin,xmax,ymin,ymax; }s[26]; struct point { int x ,y; }p[26]; int path(int s) { for(int i=0;i<n;i++) if(mat[s][i]&&!vis[i]) { vis[i]=1; if(my[i]==-1||path(my[i])) { my[i]=s; mx[s]=i; return 1; } } return 0; } bool judge(int i,int j) { if(p[j].x<s[i].xmax&&p[j].x>s[i].xmin&&p[j].y<s[i].ymax&&p[j].y>s[i].ymin) return true; return false; } int main() { int cas=0; while(scanf("%d",&n)==1&&n) { for(int i=0;i<n;i++) scanf("%d %d %d %d",&s[i].xmin,&s[i].xmax ,&s[i].ymin,&s[i].ymax); for(int i=0;i<n;i++) scanf("%d %d",&p[i].x,&p[i].y); memset(mat,0,sizeof(mat)); memset(my,-1,sizeof(my)); memset(mx,-1,sizeof(mx)); for(int i=0;i<n;i++) for(int j=0;j<n;j++) { if(judge(i,j)) mat[i][j]=1; } for(int i=0;i<n;i++) if(mx[i]==-1) { memset(vis,0,sizeof(vis)); path(i); } printf("Heap %d\n",++cas); int flag=1; for(int i=0;i<n;i++) { int y=mx[i]; mx[i]=-1; my[y]=-1; mat[i][y]=0; memset(vis,0,sizeof(vis)); if(!path(i)) { if(flag) {printf("(%c,%d)",i+'A',y+1);flag=0;} else printf(" (%c,%d)",i+'A',y+1); mx[i]=y; my[y]=i; } mat[i][y]=1; } if(!flag) printf("\n\n"); else printf("none\n\n"); } return 0; }