POJ 1486 唯一二分图匹配 好题

一道很好的题目。

大意:

很多透明的矩形薄片平摊在平面上,每个矩形薄片有数字编号。

现在给出矩形薄片的边界与编号的坐标。

求出能唯一确定的矩形薄片的字母标号与数字编号。

很容易转化成二分图的题。

开始题意弄错以为是必须全部都唯一匹配则输出匹配序,不行则输出none.

现在的题意是求关键边... 不用删边,特判就好.

#include<iostream>
#include<cstdio>
using namespace std;

struct RECT
{
 	   int minx,maxx,miny,maxy;
}rect[333];
struct POINT
{
 	   int x,y;
}point[333];
struct EDGE
{
 	   int v,next;
}E[333333];

int Edgenum,ptr[333],match[333],match2[333];
bool vis[333];

bool judge( RECT a, POINT b )
{
 	 if( a.minx<b.x && b.x<a.maxx && a.miny<b.y && b.y<a.maxy )
 	 	 return true;
 	 return false;
}
void addEdge( int u,int v )
{
 	 E[Edgenum].v=v;
 	 E[Edgenum].next=ptr[u];
 	 ptr[u]=Edgenum++;
}

bool Match( int cur,int *array,int xu=0,int xv=0 )
{
 	 for( int i=ptr[cur];i!=-1;i=E[i].next )
 	 {
	  	  if( xu==cur && xv==E[i].v )
	  	  	  continue;
	  	  if( !vis[E[i].v] )
	  	  {
		   	  vis[E[i].v]=true;
		   	  if( array[E[i].v]==-1 || Match(array[E[i].v],array,xu,xv) )
		   	  {
			   	  array[E[i].v]=cur;
			   	  return true;
			  }
   		  }
	 }
	 return false;
}

int main()
{
 	int N;int cases=0;
 	while( scanf("%d",&N)!=EOF,N )
 	{
	 	   memset( match,-1,sizeof(match) );
	 	   memset( ptr,-1,sizeof(ptr) );
	 	   Edgenum=0;
	 	   for( int i=1;i<=N;i++ )
	 	   		scanf( "%d %d %d %d",&rect[i].minx,&rect[i].maxx,&rect[i].miny,&rect[i].maxy );
	 	   for( int i=1;i<=N;i++ )
	 	   		scanf( "%d %d",&point[i].x,&point[i].y );
	 	   for( int i=1;i<=N;i++ )
	 	   for( int j=1;j<=N;j++ )
	 	   		if( judge(rect[i],point[j]) )
	 	   			addEdge(j+N,i);//用数字连方块 match为方块找数字 
	 	   int MaxMatch=0;
	 	   for( int i=N+1;i<=N+N;i++ )
	 	   {
		   		memset( vis,0,sizeof(vis) );
		   		if( Match(i,match) )
		   			MaxMatch++;
		   }
		   printf( "Heap %d\n",++cases );
		   if( MaxMatch!=N )
		   {
		   	   printf( "none\n\n" );
		   	   continue;
		   }
		   bool blank=false;
		   //枚举 断边 
		   for( int i=1;i<=N;i++ )
		   {
		   		int NowMatch=0;
		   		memset( match2,-1,sizeof(match2) );
		   		for( int j=N+1;j<=N+N;j++ )
		   		{
				 	 memset( vis,0,sizeof(vis) );
				 	 if( Match( j,match2,match[i],i ) )
				 	 	 NowMatch++;
  	 	 		}
  	 	 		if( NowMatch<MaxMatch )
  	 	 		{
				 	if( blank )
				 		printf( " " );
				 	blank=true;
				 	printf( "(%c,%d)",i+'A'-1,match[i]-N );
  	 	 			//printf( "none\n\n" );
  	 	 			//goto A;
			    }
   		   }
		   if( blank==false )
		   	   printf( "none" );
		   printf( "\n\n" );
  	}
  	return 0;
}




你可能感兴趣的:(c,struct)