pku 1486 Sorting Slides

题意:给定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;
}
posted @ 2011-09-02 09:36  枕边梦  阅读(301)  评论(2编辑  收藏  举报