POJ 3041 Asteroids 匈牙利算法 最小点覆盖
2015-08-11 10:04
330 查看
题目大意是有一块区域,上面有一些敌人,每个敌人都有一个坐标,你有一种子弹,这种子弹可以打死一列或一行的敌人,求出打死所有敌人所用最少的的子弹数。
这里将每一行看做二分图中的A集合,每一列看做B集合,集合内的元素不相交,对于每一个点(敌人)都有一个横坐标x,一个竖坐标y, 可以理解成二分图中的一条边连接了x点
y点, 要将所有的敌人干掉,便是要每一条边至少有一个点被选择,这里就转化成了最小点覆盖问题,等于最大匹配数,用匈牙利算法求解即可。
关于二分图和匈牙利算法的基础知识 这里有两个博客讲解的不错并且还有模板, 点击打开链接
点击打开链接 不过注意在第一个博客中最后一点定义和定理貌似有点问题, 还是多看一下其他人的讲解,防止被误导。
本题便是利用上文博客中的模板解决,
这里将每一行看做二分图中的A集合,每一列看做B集合,集合内的元素不相交,对于每一个点(敌人)都有一个横坐标x,一个竖坐标y, 可以理解成二分图中的一条边连接了x点
y点, 要将所有的敌人干掉,便是要每一条边至少有一个点被选择,这里就转化成了最小点覆盖问题,等于最大匹配数,用匈牙利算法求解即可。
关于二分图和匈牙利算法的基础知识 这里有两个博客讲解的不错并且还有模板, 点击打开链接
点击打开链接 不过注意在第一个博客中最后一点定义和定理貌似有点问题, 还是多看一下其他人的讲解,防止被误导。
本题便是利用上文博客中的模板解决,
#include <cstdio> #include <cstring> using namespace std; const int MAXN=510; int uN,vN; int g[MAXN][MAXN]; int linker[MAXN]; bool used[MAXN]; bool dfs(int u) { int v; for(v=1;v<=vN;v++) // 注意这里是从1开始,使用模板的话注意根据题目选择循环的始末点,hungary函数中的循环亦是如此 if(g[u][v]&&!used[v]) { used[v]=true; if(linker[v]==-1||dfs(linker[v])) {//找增广路,反向 linker[v]=u; return true; } } return false; } int hungary() { int res=0; int u; memset(linker,-1,sizeof(linker)); for(u=1;u<=uN;u++) { memset(used,0,sizeof(used)); if(dfs(u)) res++; } return res; } int main() { //freopen("in.txt","r",stdin); int n,k; while(scanf("%d%d",&n,&k)!=EOF) { vN=uN=n; int x,y; memset(g,0,sizeof(g)); for(int i=0;i<k;i++) { scanf("%d%d",&x,&y); g[x][y]=1; } int ans=hungary(); printf("%d\n",ans ); } }
相关文章推荐
- 程序员很穷
- PHP面向对象(OOP):__toString()方法
- Creating Isomorphic Apps with Node.js, React, and Express
- 转转
- 编译原理第一章学习总结
- poj 1258 Agri-Net 【Prim&Kruskal】
- CodeVS 1213 解的个数
- Java I/O 操作及优化建议
- 201508110842_《Javascript权威指南(第六版)——方法借用,私有状态,construct重构和工厂方法》(P225-233)
- @清晰掉 GNU C __attribute__
- win10怎么开wifi热点?win10wifi热点开启图文步骤
- 寻找OEP
- 18-Map集合-07-常用对象API(集合框架-Map集合-HashMap存储自定义对象)
- 华为训练题目:初级——(练习用)挑7
- php继承详解 extends
- 水仙花数
- ios内存管理 part1
- vector的用法
- Leetcode:Convert Sorted List to Binary Search Tree
- LINQ体验(1)——Visual Studio 2008新特性