题目
给出一个矩阵,上面有敌人,每个子弹可以打出一横行或者一竖行,问最少用多少子弹消灭都有敌人,如:
X.X
.X.
.X.
x表示敌人,显然用两个子弹就可以解决所有敌人。
题解
这题的建图在于一边为行,一边为列,有敌人的行和列连边,求最小点覆盖=最大匹配
代码
#include <cstdio>
#include <cstring>
using namespace std;
int n,k,ans;
int ls[505],ne[10004],y[10004],link[505];
bool cover[505];
bool dfs(int k){
for (int i=ls[k];i;i=ne[i])
if (!cover[y[i]]){
int t=link[y[i]];
link[y[i]]=k;
cover[y[i]]=1;
if (t==0||dfs(t)) return true;
link[y[i]]=t;
}
return false;
}
int main(){
scanf("%d%d",&n,&k);
for (int i=1;i<=k;i++){
int a,b;
scanf("%d%d",&a,&b);
ne[i]=ls[a];ls[a]=i;y[i]=b;
}
for (int i=1;i<=n;i++){
memset(cover,0,sizeof(bool)*502);
dfs(i);
}
for (int i=1;i<=n;i++)
if (link[i]) ans++;
printf("%d\n",ans);
}