题意:给出几张纸的覆盖范围,和几个标号的坐标,求最多的可以确定这些纸的标号
思路:每张纸作为X部,标号作为Y部,如果标号在纸中,则连一条边,求最大匹配。
检验是否有多重的匹配时,可以枚举删除匹配边,再对其进行匹配,若找到匹配边,
则该纸的标号不确定。
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define inf 2147483648
#define pi 3.1415926535898
#define N 1005
#define ll long long
int mat[N][N],vis[N],ans[N],n;
struct node
{
int xmin,xmax,ymin,ymax;
}p[N];
int dfs(int x)
{
for(int i=1;i<=n;i++)
{
if(vis[i]==0&&mat[x][i])
{
vis[i]=1;
if(ans[i]==0||dfs(ans[i]))
{
ans[i]=x;
return 1;
}
}
}
return 0;
}
int match()
{
int sum=0;
for(int i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis));
if(dfs(i)) sum++;
}
return sum;
}
int main()
{
int x,y;
int Case=1;
while(scanf("%d",&n)&&n)
{
int i,j;
memset(mat,0,sizeof(mat));
memset(ans,0,sizeof(vis));
for(i=1;i<=n;i++)
scanf("%d%d%d%d",&p[i].xmin,&p[i].xmax ,&p[i].ymin ,&p[i].ymax );
for(i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
for(j=1;j<=n;j++)
{
if(x>=p[j].xmin &&x<=p[j].xmax &&y>=p[j].ymin &&y<=p[j].ymax )
{
mat[i][j]=1;//左边代表数字,右边代表字母
}
}
}
printf("Heap %d\n",Case++);//先任意求一次最大匹配
if(match()
int temp,cnt=0;
for(i=1;i<=n;i++)
{
temp=ans[i];
ans[i]=0;//把位置腾出来
mat[temp][i]=0;//同时把边删掉,这样就无法达到原来的匹配
memset(vis,0,sizeof(vis));
if(!dfs(temp))//如果没有新的匹配方案诞生,说明这是一条关键边
{
cnt++;
ans[i]=temp;
if(cnt>1)
printf(" ");
printf("(%c,%d)",i-1+'A',temp);
}
mat[temp][i]=1;//把图复原
}
if(cnt==0) printf("none\n\n");
else
printf("\n\n");
}
}