【题目链接】 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 ",++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; }