自从看了二分图之后,感觉好多题目的解题方法真的跟以往的思维方式不一样了。。。。这可能就是抽象思维吧。
这个题目的意思是在网格中有k个小行星,你的炮弹只能一次只能摧毁一行或者一列的小行星,让你用求出最小的炮弹数目来毁掉这些小行星。
这个题目抽象的地方在炮弹当做顶点把小行星当做边,把发射的光束当做顶点,然后建图。。。。这样建出图之后求这个二分图的最大匹配,因为对于二分图来说,
最小顶点覆盖=最大匹配,求出最大匹配数来就是对应的最小顶点覆盖数。
#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <cmath>
#define maxn 1010
#define Max 0x3f3f3f3f
using namespace std;
int n,m;
vector<int>G[maxn];
bool update[maxn];
void add(int s,int t)
{
G[s].push_back(t);
G[t].push_back(s);
}
int match[maxn];
void Init()
{
for (int i=1;i<=2*n;i++)
{
G[i].clear();
}
}
bool Dfs(int now)
{
update[now]=true;
for (int i=0;i<G[now].size();i++)
{
int t=G[now][i];
if (match[t]==-1||(!update[match[t]]&&Dfs(match[t])))//??????????????
{
match[now]=t;
match[t]=now;
return true;
}
}
return false;
}
void Get()
{
int res=0;
memset(match,-1,sizeof(match));
for (int i=1;i<=2*n;i++)
{
if (match[i]==-1)
{
fill(update+1,update+2*n+1,false);
if (Dfs(i))
{
res++;
}
}
}
cout<<res<<endl;
}
int main()
{
int a,b;
while(scanf("%d %d",&n,&m)!=EOF)
{
Init();
while(m--)
{
scanf("%d %d",&a,&b);
add(a,b+n);
}
Get();
}
return 0;
}