HDU4619+匈牙利

/*

匈牙利算法

二分匹配 最小点覆盖=最大匹配。

即踢掉最小点覆盖

*/

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<algorithm>

#include<iostream>

#include<queue>

#include<map>

#include<math.h>

using namespace std;

typedef long long ll;

//typedef __int64 int64;

const int maxn = 1015;

const int inf = 0x7fffffff;

const double pi=acos(-1.0);

const double eps = 1e-8;

struct Edge{

	int v,next;

}edge[ maxn<<4 ];

struct Node{

	int x,y;

}sum[ maxn<<1 ];

int cnt,head[ maxn<<1 ];

int vis[ maxn<<1 ],mylink[ maxn<<1 ];

void init(){

	cnt = 0;

	memset( head,-1,sizeof( head ) );

}

void addedge( int a,int b ){

	edge[ cnt ].v = b;

	edge[ cnt ].next = head[ a ];

	head[ a ] = cnt++;

}

bool km( int u ){

	for( int i=head[ u ];i!=-1;i=edge[ i ].next ){

		int v = edge[ i ].v;

		if( vis[ v ]==0 ){

			vis[ v ] = 1;

			if( mylink[ v ]==-1||km( mylink[v] ) ){

				mylink[ v ] = u;

				return true;

			}

		}

	}

	return false;

}

int solve( int n,int m ){

	memset( mylink,-1,sizeof( mylink ) );

	int ans = 0;

	for( int i=1;i<=n;i++ ){

		memset( vis,0,sizeof( vis ) );

		if( km(i) )

			ans++;

	}

	return ans;

}

bool Judge( int i,int j ){

	int x1 = sum[i].x;

	int y1 = sum[i].y;

	int x2 = sum[j].x;

	int y2 = sum[j].y;

	if( x1==x2 ){

		if( y1==y2 ) return true;

		if( y1==y2+1 ) return true;

	}

	if( x1+1==x2 ){

		if( y1==y2 ) return true;

		if( y1==y2+1 ) return true;

	}

	return false;

}	

		 

int main(){

	int n,m;

	while( scanf("%d%d",&n,&m)==2,n+m ){

		init();

		int cc = 1;

		for( int i=1;i<=n;i++ )

			scanf("%d%d",&sum[cc].x,&sum[cc].y),cc++;

		for( int j=1;j<=m;j++ )

			scanf("%d%d",&sum[cc].x,&sum[cc].y),cc++;

		for( int i=1;i<=n;i++ ){

			for( int j=n+1;j<cc;j++ ){

				if( Judge( i,j ) ){

					addedge( i,j );

				}

			}

		}

		printf("%d\n",cc-1-solve( n,m ));

	}

	return 0;

}



你可能感兴趣的:(HDU)