这里是不是应该写下什么是匈牙利算法(找到了一个非常容易理解的一个讲解趣味算法),这位大佬已经讲的很详细了(和这我道题雷同二分图最大匹配数)~~~
题意:
在一个n*n的网格中,有k个炸弹吧,每次可以删除一行或者一列,要清除这所有炸弹最少要删除几次。
思路(copy:参考链接):
将每行、每列分别看作一个点,对于case的每一个行星坐标(x,y),将第x行和第y列连接起来,例如对于输入:
(1,1)、(1,3)、(2,2)、(3,2)4点构造图G:
这样,每个点就相当于图G的一条边,消灭所有点=消灭图G的所有边,又要求代价最少,即找到图G上的最少的点使得这些点覆盖了所有边。
v2_used[]是记录是否遍历过v2
v2_link[]是记录v2的y匹配的v1编号x;
#include<stdio.h>
#include<string.h>
int map[505][505];
int v2_link[10005];
int v2_used[10005];
int res,v1,v2;
bool dfs(int x)
{
int y;
for(y=1;y<=v2;y++)
{
if(map[x][y]==1&&!v2_used[y])
{
v2_used[y]=1;
if(v2_link[y]==0||dfs(v2_link[y]))
{
v2_link[y]=x;
return true;
}
}
}
return false;
}
void search()
{
int x;
for(x=1;x<=v1;x++)
{
memset(v2_used,0,sizeof(v2_used));
if(dfs(x))
res++;
}
}
int main()
{
int x,y,i,n,k;
scanf("%d%d",&n,&k);
v1=v2=n;
memset(map,0,sizeof(map));
res=0;
for(i=1;i<=k;i++)
{
scanf("%d%d",&x,&y);
map[x][y]=1;
}
search();
printf("%d\n",res);
return 0;
}