POJ 3041 Asteroids(二分匹配-hungary)
2015-12-31 13:27
477 查看
Description
有一个n*n的方阵,方阵上有k个障碍物,每一次可以消除一行或者一列上所有的障碍物,问最少需要几次能够消除所有的障碍物
Input
第一行为两个整数n和k表示矩阵行列数和障碍物数量,之后k行每行两个整数i和j表示该障碍物处于第i行第j列
Output
输出最少几次才能消除所有障碍物
Sample Input
3 4
1 1
1 3
2 2
3 2
Sample Output
2
Solution
二分匹配,将每行看作一排点,每列看作一排点,对于每个障碍物(i,j),从第一排点的i到第二排点的j建边,建完图后我们需要找最少的点覆盖所有的边,问题转化为求这张图的最小点覆盖,即最大匹配数
Code
有一个n*n的方阵,方阵上有k个障碍物,每一次可以消除一行或者一列上所有的障碍物,问最少需要几次能够消除所有的障碍物
Input
第一行为两个整数n和k表示矩阵行列数和障碍物数量,之后k行每行两个整数i和j表示该障碍物处于第i行第j列
Output
输出最少几次才能消除所有障碍物
Sample Input
3 4
1 1
1 3
2 2
3 2
Sample Output
2
Solution
二分匹配,将每行看作一排点,每列看作一排点,对于每个障碍物(i,j),从第一排点的i到第二排点的j建边,建完图后我们需要找最少的点覆盖所有的边,问题转化为求这张图的最小点覆盖,即最大匹配数
Code
#include<cstdio> #include<iostream> #include<cstring> using namespace std; #define maxn 555 int uN,vN;//u,v数目 int g[maxn][maxn];//编号是0~n-1的 int linker[maxn]; bool used[maxn]; bool dfs(int u) { int v; for(v=0;v<vN;v++) 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=0;u<uN;u++) { memset(used,0,sizeof(used)); if(dfs(u)) res++; } return res; } int main() { int n,k; while(~scanf("%d%d",&n,&k)) { memset(g,0,sizeof(g)); uN=vN=n; while(k--) { int x,y; scanf("%d%d",&x,&y); g[x-1][y-1]=1; } int ans=hungary(); printf("%d\n",ans); } return 0; }
相关文章推荐
- 一看就懂的ReactJs入门教程(精华版)
- Bootstrap 是一个用于快速开发 Web 应用程序和网站的前端框架
- Git CMD - merge: Join two or more development histories together
- 自然数的拆分组数
- ubuntu14.04设置静态ip
- zookeeper 的监控工具
- 你好2016!
- C++ 学习 (容器与继承)
- React-Native学习指南
- iOS 简单的使用UIBezierPath绘制
- React-Native学习指南
- MQTT——服务器搭建(一)
- codevs 3305 水果姐逛水果街二
- Git CMD - checkout: Switch branches or restore working tree files
- 自定义布局机制
- .net 分布式架构之分布式缓存中间件
- 传递闭包计算warshall算法C语言实现
- 诡异奇怪的“虚拟硬盘可用空间不足”告警
- 虚拟机win2012安装
- Backbone.js 为复杂Javascript应用程序提供模型(models)、集合(collections)、视图(views)的结构