题意:给定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;
}