poj 3041 Asteroids 【匈牙利算法】
2015-06-15 14:50
274 查看
题目链接:http://poj.org/problem?id=3041
题意:n*n矩阵上有行星,每次只能在一行或一列放一发子弹,消灭本行或列的所有行星,求消灭所有行星的最小消耗子弹数目。
解法:二分图,行为一个顶点集,列为另一顶点集。题目转化成为选择最少的一些点(x或y),使得从这些点与所有的边相邻,其实这就是最小点覆盖问题。
代码:
题意:n*n矩阵上有行星,每次只能在一行或一列放一发子弹,消灭本行或列的所有行星,求消灭所有行星的最小消耗子弹数目。
解法:二分图,行为一个顶点集,列为另一顶点集。题目转化成为选择最少的一些点(x或y),使得从这些点与所有的边相邻,其实这就是最小点覆盖问题。
代码:
[code]#include <stdio.h> #include <ctime> #include <math.h> #include <limits.h> #include <complex> #include <string> #include <functional> #include <iterator> #include <algorithm> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #include <list> #include <bitset> #include <sstream> #include <iomanip> #include <fstream> #include <iostream> #include <ctime> #include <cmath> #include <cstring> #include <cstdio> #include <time.h> #include <ctype.h> #include <string.h> #include <assert.h> using namespace std; int p[510][510]; int n; int k; int a,b; int book[510]; int match[510]; bool dfs(int u) { for (int i = 1; i <= n; i++) { if (book[i] == 0 && p[u][i] == 1) { book[i] = 1; if (match[i] == 0 || dfs(match[i])) { match[i] = u; return true; } } } return false; } int main() { while (scanf("%d%d",&n,&k)!=EOF) { memset(p,0,sizeof(p)); memset(match,0,sizeof(match)); while(k--) { scanf("%d%d",&a,&b); p[a][b] = 1; } int ans = 0; for(int i=1;i<=n;i++) { memset(book, 0, sizeof(book)); if (dfs(i)) ans++; } printf("%d\n",ans); } return 0; }
相关文章推荐
- Linux 驱动之块设备 (卸载块模块就死机了,尚未解决) (一)
- javaweb基本组件之listener的使用
- BZOJ1003
- C#模拟POST登录cnblogs并发布文章
- 测试图片
- 职场第一天
- MySQL写入插入数据优化配置
- Python实现简单HTML表格解析的方法
- solr 重要的知识点
- 云提供的各种级别的服务
- 关于图片对象BitmapImage的BitmapCreateOptions
- POJ 1330:Nearest Common Ancestors
- visual studio自动导入 using 的快捷键
- C#--Web数据分页
- POJ 1330:Nearest Common Ancestors
- 验证邮箱的正则表达式
- 使用xpdf解析中文PDF详细过程
- sublime编译运行c++
- Python作用域
- Adobe Acrobat Pro 11安装激活