题目链接:http://poj.org/problem?id=1486
思路,匈牙利算法找到最大匹配,然后对每一条匹配的边进行检查,看是否可以有替换他的另一种最大匹配(即map中删掉这条匹配的边看能否找到最大增广路径),注意在删掉这条边是match对应的值应设置为初始值,每一条边检查完恢复map中之前删掉的路径。
#include<cstdio>
#include<cstring>
using namespace std;
const int num=505;
struct node
{
int xmin,xmax,ymin,ymax;
}data[num];
int n,map[num][num],match[num],vis[num],tx,ty;
int ok(int a)
{
if(tx>=data[a].xmin&&tx<=data[a].xmax&&ty>=data[a].ymin&&ty<=data[a].ymax)
return 1;
return 0;
}
int deal(int a)
{
int i;
for(i=0;i<n;i++)
if(vis[i]==0&&map[a][i])
{
vis[i]=1;
if(match[i]==-1||deal(match[i]))
{
match[i]=a;
return 1;
}
}
return 0;
}
int main()
{
int i,j,cas=0,ans,t,flag;
//freopen("in.txt","r",stdin);
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
cas++;
printf("Heap %d\n",cas);
memset(map,0,sizeof(map));
memset(match,-1,sizeof(match));
for(i=0;i<n;i++)
scanf("%d%d%d%d",&data[i].xmin,&data[i].xmax,&data[i].ymin,&data[i].ymax);
for(i=0;i<n;i++)
{
scanf("%d%d",&tx,&ty);
for(j=0;j<n;j++)
{
if(ok(j))
map[i][j]=1;
}
}
for(i=0;i<n;i++)
{
memset(vis,0,sizeof(vis));
ans+=deal(i);
}
//for(i=0;i<n;i++) printf("%d ",match[i]);printf("\n");
flag=0;
for(i=0;i<n;i++)
{
if(match[i]==-1)
continue;
t=match[i];
match[i]=-1;
map[t][i]=0;
memset(vis,0,sizeof(vis));
if(deal(t)==0)
{
match[i]=t;
if(flag==0)
printf("(%c,%d)",i+'A',match[i]+1);
else
printf(" (%c,%d)",i+'A',match[i]+1);
flag++;
}
map[t][i]=1;
}
if(flag==0)
printf("none");
printf("\n\n");
}
return 0;
}