POJ 3041:Asteroids:最小点覆盖

Asteroids
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 14619   Accepted: 7962

Description

Bessie wants to navigate her spaceship through a dangerous asteroid field in the shape of an N x N grid (1 <= N <= 500). The grid contains K asteroids (1 <= K <= 10,000), which are conveniently located at the lattice points of the grid. 

Fortunately, Bessie has a powerful weapon that can vaporize all the asteroids in any given row or column of the grid with a single shot.This weapon is quite expensive, so she wishes to use it sparingly.Given the location of all the asteroids in the field, find the minimum number of shots Bessie needs to fire to eliminate all of the asteroids.

Input

* Line 1: Two integers N and K, separated by a single space. 
* Lines 2..K+1: Each line contains two space-separated integers R and C (1 <= R, C <= N) denoting the row and column coordinates of an asteroid, respectively.

Output

* Line 1: The integer representing the minimum number of times Bessie must shoot.

Sample Input

3 4
1 1
1 3
2 2
3 2

Sample Output

2

Hint

INPUT DETAILS: 
The following diagram represents the data, where "X" is an asteroid and "." is empty space: 
X.X 
.X. 
.X. 

OUTPUT DETAILS: 
Bessie may fire across row 1 to destroy the asteroids at (1,1) and (1,3), and then she may fire down column 2 to destroy the asteroids at (2,2) and (3,2).

Source

USACO 2005 November Gold
这个题目属于标准的图论题目,需要适当的转换,建立适当的图来进行结题。建立二分图,设置x坐标作为A点集,y坐标作为B点集。那么每个点转化成连接A、B点集的边。问题就转化成最小点覆盖问题,即若选定一个点,那么于此点相连的所有边都被选定,求满足选定所有边的最少的点集。最小点覆盖问题可以用二分图的最大匹配来解。最小点数=最大匹配数(此处不在证明,详情请看上篇文章)。这样通过构建二分图求解最大匹配数,来求解该问题的最小点覆盖。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int n,k,a[505][505],use[505],result[505];
int count;
void init()
{
	int i,j;
	int ta,tb;
	memset(a,0,sizeof(a));
	memset(result,0,sizeof(result));
	count=0;
	while(k--)
	{
		scanf("%d%d",&ta,&tb);
		a[ta][tb]=1;
	}
}
int find(int x)
{
	int i,j;
	for(i=1;i<=n;i++)
	{
		if(a[x][i]&&!use[i])
		{
			use[i]=1;
			if(!result[i]||find(result[i]))
			{
				result[i]=x;
				return 1;
			}
		}
	}
	return 0;
}
int main()
{
	int i,j;

	while(scanf("%d%d",&n,&k)!=EOF)
	{
		init();
		for(i=1;i<=n;i++)
		{
			memset(use,0,sizeof(use));
			if(find(i))
				count++;
		}
		printf("%d\n",count);
	}
	return 0;
}


你可能感兴趣的:(POJ 3041:Asteroids:最小点覆盖)