POJ 3041 Asteroids 二分图最小点覆盖
2016-07-25 22:22
453 查看
给N和K,N代表N*N的矩阵,K代表接下来有K个格子,每个格子上有一个小行星,
他的武器每次可以干掉某一行或者某一列的所有小行星,然后问最少使用 多少次该武器
最小点覆盖:就是对于一个图,选取最少数量的点S,使得对于所有的边,都至少有一端点是S中的点
König定理:二分图中的最小覆盖点数==最大匹配数
这个题建图,每行对应为左边的每个点,每列对应为右边的点,然后如果(i,j)有小行星,就连一条边
然后使用最少的武器就是,选取最少的点,使得所有边都至少有一端是被选取的
所以就是二分图最小点覆盖,就是最大匹配数,然后匈牙利就可以搞过去
他的武器每次可以干掉某一行或者某一列的所有小行星,然后问最少使用 多少次该武器
最小点覆盖:就是对于一个图,选取最少数量的点S,使得对于所有的边,都至少有一端点是S中的点
König定理:二分图中的最小覆盖点数==最大匹配数
这个题建图,每行对应为左边的每个点,每列对应为右边的点,然后如果(i,j)有小行星,就连一条边
然后使用最少的武器就是,选取最少的点,使得所有边都至少有一端是被选取的
所以就是二分图最小点覆盖,就是最大匹配数,然后匈牙利就可以搞过去
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <string> #include <fstream> #include <list> #include <stack> #include <queue> #include <deque> #include <algorithm> #include <map> #include <set> #include <vector> #define maxn 505 #define maxm 505 using namespace std; bool graph[maxn][maxm]; bool vis[maxm], flag; int match[maxn]; int N, K; bool find(int x) { int j; for (j = 0; j < N; j++) { if (graph[x][j] == true && vis[j] == false) { vis[j] = true; if (match[j] == -1 || find(match[j])) { match[j] = x; return true; } } } return false; } int main() { //freopen("input.txt", "r", stdin); int x, y; int ans = 0; scanf("%d%d", &N, &K); memset(graph, 0, sizeof(graph)); memset(match, -1, sizeof(match)); for (int i = 0; i < K; i++) { scanf("%d%d", &x, &y); --x; --y; graph[x][y] = true; } for (int i = 0; i < N; i++) { memset(vis, 0, sizeof(vis)); if (find(i)) ans += 1; } printf("%d\n", ans); //while (1); return 0; }
相关文章推荐
- android-Notification.InboxStyle
- Python中的分片
- HDU 5729 - Rigid Frameworks
- JavaScript事件机制——细思极恐
- **MYSQL** 系列十
- ODS 和 数据仓库
- PHP中的一些遗漏点
- android-Notification.Builder
- Docker的安装配置及使用详解
- iOS objc_msgSend函数
- sed常用命令
- 前端常见面试题总结---第二篇
- 线程池类型
- NYOJ 37
- AngularJS Scope(作用域)
- Spring学习笔记
- scala基础23-内部函数
- man命令和history命令的一些小技巧
- JDK和Tomcat环境变量,以及用MyEclipse新建Web Project测试Tomcat Server
- 9月java货车版速记