题意:
假如你现在正处在一个N*N的矩阵中,这个矩阵里面有K个障碍物,你拥有一把武器,一发弹药一次能消灭一行或一列的障碍物,求最小的弹药消灭全部障碍物
输入为: N K输出为: 花费最小的弹药数
思路:将i行作为X集合,将j列作为Y集合,这样原来的问题—用最少的炮弹打掉全部障碍物,转化为了这么一个问题:
在二分图中选择尽量少的点,使得每条边至少有一个端点被选中
裸的最小点覆盖问题,运用结论:最小覆盖数等于最大匹配数 即可
代码如下:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N = 600; int n, k; bool lin[N][N]; int used[N], arr[N]; bool find(int x) { for(int j = 1; j <= n; j++) { if(lin[x][j] == true && used[j] == 0) { used[j] = 1; if(arr[j] == 0 || find(arr[j])) { arr[j] = x; return true; } } } return false; } int main() { int r, c; while(~scanf("%d%d", &n, &k)) { memset(lin, false , sizeof(lin)); memset(arr, 0, sizeof(arr)); for(int i = 1; i <= k; i++) { scanf("%d%d", &r, &c); lin[r][c] = true; } int all = 0; for(int i = 1; i <= n; i++) { memset(used, 0, sizeof(used)); if(find(i)) all++; } printf("%d\n", all); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/doris1104/article/details/46730265