UVa 11419 SAM I AM (最小点覆盖,匈牙利算法)
来源:互联网 发布:哈利波特英文原版淘宝 编辑:程序博客网 时间:2024/05/20 05:24
题目:https://vjudge.net/contest/136139#problem/E
题意:
有一个矩阵中放置的一写东西,然后你有一门炮,每次能横向或纵向开一炮,是这一行所有的东西摧毁。问你最少花多少炮弹摧毁所有的东西?输出一组解
分析:
这题是求最小覆盖数,以前做过不出输出方案的
最小覆盖数=最大匹配数
求最大匹配数用匈牙利算法即可
输出最小覆盖集:
从未匹配点找增广路,划分S和T集合
那么在S’和T中的就是最小覆盖集
可以这么理解S’中的是未匹配的,每个未匹配的都需要安排一个发射点
T中的是和S中匹配的,安排一个发射点就能都把匹配的都打掉了
代码:
// UVa11419 SAM I AM// Rujia Liu#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;const int maxn = 1000 + 5; // 单侧顶点的最大数目// 二分图最大基数匹配struct BPM { int n, m; // 左右顶点个数 vector<int> G[maxn]; // 邻接表 int left[maxn]; // left[i]为右边第i个点的匹配点编号,-1表示不存在 bool T[maxn]; // T[i]为右边第i个点是否已标记 int right[maxn]; // 求最小覆盖用 bool S[maxn]; // 求最小覆盖用 void init(int n, int m) { this->n = n; this->m = m; for(int i = 0; i < n; i++) G[i].clear(); } void AddEdge(int u, int v) { G[u].push_back(v); } bool match(int u) { S[u] = true; for(int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if (!T[v]) { T[v] = true; if (left[v] == -1 || match(left[v])) { left[v] = u; right[u] = v; return true; } } } return false; } // 求最大匹配 int solve() { memset(left, -1, sizeof(left)); memset(right, -1, sizeof(right)); int ans = 0; for(int u = 0; u < n; u++) { // 从左边结点u开始增广 memset(S, 0, sizeof(S)); memset(T, 0, sizeof(T)); if(match(u)) ans++; } return ans; } // 求最小覆盖。X和Y为最小覆盖中的点集 int mincover(vector<int>& X, vector<int>& Y) { int ans = solve(); memset(S, 0, sizeof(S)); memset(T, 0, sizeof(T)); for(int u = 0; u < n; u++) if(right[u] == -1) match(u); // 从所有X未盖点出发增广 for(int u = 0; u < n; u++) if(!S[u]) X.push_back(u); // X中的未标记点 for(int v = 0; v < m; v++) if(T[v]) Y.push_back(v); // Y中的已标记点 return ans; }};BPM solver;int R, C, N;int main() { int kase = 0; while(scanf("%d%d%d", &R, &C, &N) == 3 && R && C && N) { solver.init(R, C); for(int i = 0; i < N; i++) { int r, c; scanf("%d%d", &r, &c); r--; c--; solver.AddEdge(r, c); } vector<int> X, Y; int ans = solver.mincover(X, Y); printf("%d", ans); for(int i = 0; i < X.size(); i++) printf(" r%d", X[i]+1); for(int i = 0; i < Y.size(); i++) printf(" c%d", Y[i]+1); printf("\n"); } return 0;}
0 0
- UVa 11419 SAM I AM (最小点覆盖,匈牙利算法)
- UVA 11419 SAM I AM(最小点覆盖)
- UVA 11419SAM I AM (最小点覆盖)
- Uva 11419 SAM I AM (最小点覆盖)
- UVA 11419 SAM I AM 二分匹配最小覆盖点
- UVA 11419 SAM I AM 二分图+最小覆盖点
- UVA 11419 SAM I AM (最小点覆盖)
- uva 11419 - SAM I AM(最小覆盖)
- Uva - 11419 - SAM I AM(二分图最小点覆盖)
- UVA 11419 SAM I AM(二分图最小点覆盖)
- UVA 11419 - SAM I AM(二分图匹配+最小点覆盖)
- uva 11419 SAM I AM 求出二分图的最小点覆盖集
- UVALive 11419 SAM I AM (最小点覆盖输出)
- UVa11419 SAM I AM(构造最小点覆盖)
- uva 11419 SAM I AM (最小覆盖 König定理)
- SAM I AM(二分图的最小点覆盖)
- UVA 11419 SAM I AM(二分图最小覆盖+答案输出)
- uva11419 SAM I AM(最小顶点覆盖+输出顶点)
- Java 编程----(一.基础)
- android6.0动态权限
- TCP-IP学习笔记八:RPC(Netty和Spring)实现webServer框架
- Wireshark数据抓包教程之认识捕获分析数据包
- 从一道面试题来认识java类加载时机与过程 - 天魂地煞
- UVa 11419 SAM I AM (最小点覆盖,匈牙利算法)
- makefile调试2--显示而不执行make
- Android中文件简单存储(写入 读取)
- 本地编译mybatis的源码
- 微信点击按钮关闭当前页面回到微信对话窗口
- TCP/IP四层模型
- win7、win10环境下的maven的环境变量配置
- opencv 中Mat的数据结构
- java小程序实例 闰年