传送门:POJ3041
题意:有一个N*M的地图,上面有一些小行星,每次可以选择一行或者一列炸掉,问最少多少次能把所有的小行星炸光。
思路:这题纯粹是锻炼建图的思维,将行和列抽象成点,若行和列的交点为小行星则建一条边,建好图以后问题就转化成了求二分图最大匹配问题。随便一个匈牙利或者HK算法都能搞定。
代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<map>
#define ll long long
#define pi acos(-1)
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
typedef pair<int,int>P;
const int MAXN=100010;
int mp[505][505],book[505],match[505];
int n,m;
bool dfs(int v)
{
for(int i=1;i<=n;i++)
{
if(!book[i]&&mp[v][i])
{
book[i]=1;
if(!match[i]||dfs(match[i]))
{
match[i]=v;
return 1;
}
}
}
return 0;
}
int main()
{
int x,y;
while(~scanf("%d%d",&n,&m))
{
memset(mp,0,sizeof(mp));
for(int i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
mp[x][y]=1;
}
int ans=0;
memset(match,0,sizeof(match));
for(int i=1;i<=n;i++)
{
memset(book,0,sizeof(book));
if(dfs(i))
ans++;
}
printf("%d\n",ans);
}
return 0;
}