【题目链接】 http://poj.org/problem?id=1486
【题目大意】
给出每张幻灯片的上下左右坐标,每张幻灯片的页码一定标在这张幻灯片上,
现在问你有没有办法唯一鉴别出一些幻灯片
【题解】
我们先求一遍匹配,然后对于匹配的边进行删去后再匹配,
如果匹配数量发生变化,则说明这条边不是完美匹配,
测试每一条边之后,我们就能得到完美匹配的边,就是答案。
【代码】
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXV=500;
int n,nedges,G[MAXV][MAXV],use[MAXV],match[MAXV],edgs[MAXV][2],mark[MAXV];
bool dfs(int x){
for(int i=1;i<=n;i++){
if(use[i]==0&&G[x][i]){
use[i]=1;
int j=match[i];
if(j==-1||dfs(j)){
match[i]=x;
return 1;
}
}
}return 0;
}
int bipartite_matching(){
int count=0;
memset(match,-1,sizeof(match));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)use[j]=0;
if(dfs(i))count++;
}return count;
}
int x,y,xmin[MAXV],xmax[MAXV],ymin[MAXV],ymax[MAXV],cas=0;
int main(){
while(scanf("%d",&n) && n){
memset(G,0,sizeof(G));
memset(mark,1,sizeof(mark));
for(int i=1;i<=n;i++)scanf("%d%d%d%d",&xmin[i],&xmax[i],&ymin[i],&ymax[i]);
for(int i=1;i<=n;i++){
scanf("%d%d",&x,&y);
for(int j=1;j<=n;j++)
if(x>=xmin[j]&&x<=xmax[j]&&y>=ymin[j]&&y<=ymax[j])G[i][j]=1;
}printf("Heap %d\n",++cas);
if(bipartite_matching()==n){
nedges=n;
for(int i=1;i<=n;i++){
edgs[i][0]=i;
edgs[i][1]=match[i];
}
for(int i=1;i<=n;i++){
G[edgs[i][1]][edgs[i][0]]=0;
if(bipartite_matching()==n){
mark[i]=0;
nedges--;
}G[edgs[i][1]][edgs[i][0]]=1;
}
}else puts("none");
if(nedges==0)puts("none");
else{
for(int i=1;i<=n;i++)if(mark[i])printf("(%c,%d) ",edgs[i][0]+'A'-1,edgs[i][1]);
puts("");
}puts("");
}return 0;
}