问题 A: [Usaco2005 nov]Asteroids 穿越小行星群
时间限制: 1 Sec 内存限制: 256 MB题目描述
贝茜想驾驶她的飞船穿过危险的小行星群.小行星群是一个NxN的网格(1≤N≤500),在网格内有K个小行星(1≤K≤10000). 幸运地是贝茜有一个很强大的武器,一次可以消除所有在一行或一列中的小行星,这种武器很贵,所以她希望尽量地少用.给出所有的小行星的位置,算出贝茜最少需要多少次射击就能消除所有的小行星.
输入
第1行:两个整数N和K,用一个空格隔开.
第2行至K+1行:每一行有两个空格隔开的整数R,C(1≤R,C≤N),分别表示小行星所在的行和列.
输出
一个整数表示贝茜需要的最少射击次数,可以消除所有的小行星
样例输入
3 4
1 1
1 3
2 2
3 2
样例输出
2
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
const int N = 2005;
bool vis[N];
int link[N],head[N];
int cnt,n,k;
struct Edge
{
int to;
int next;
};
Edge edge[N*N];
void Init()
{
cnt = 0;
memset(head,-1,sizeof(head));
}
void add(int u,int v)
{
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt++;
}
bool dfs(int x)
{
int v;
for(int i=head[x];i!=-1;i=edge[i].next)
{
v=edge[i].to;
if(!vis[v])
{
vis[v]=1;
if(link[v]==-1||dfs(link[v]))
{
link[v]=x;
return true;
}
}
}
return false;
}
int match()
{
int ans=0;
memset(link,-1,sizeof(link));
for(int i=0;i<n;i++)
{
memset(vis,0,sizeof(vis));
if(dfs(i))ans++;
}
return ans;
}
int main()
{
// freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&k);
Init();
for(int i=1;i<=k;i++)
{
int r,c;
cin>>r>>c;
add(r-1,c-1);
}
printf("%d\n",match());
return 0;
}