题意:给定一个 n * m 的矩阵,有一些格子有目标,每次可以消灭一行或者一列,问你最少要几次才能完成。

析:把 行看成 X,把列看成是 Y,每个目标都连一条线,那么就是一个二分图的最小覆盖数,这个答案就是二分图的最大匹配,在输出解的时候,就是从匈牙利树上,从X的未盖点出发,然后标记X和Y,最后X中未标记的和Y标记的就是答案。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#include <list>
#include <assert.h>
#include <bitset>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a, b, sizeof a)
#define sz size()
#define pu push_up
#define pd push_down
#define cl clear()
#define all 1,n,1
#define FOR(i,x,n) for(int i = (x); i < (n); ++i)
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 1e20;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 2000 + 10;
const LL mod = 1e9 + 7;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c) {
return r >= 0 && r < n && c >= 0 && c < m;
} struct Edge{
int to, next;
};
Edge edge[maxn*maxn/4];
int head[maxn], cnt;
int match[maxn];
bool used[maxn];
bool visx[maxn], visy[maxn]; void addEdge(int u, int v){
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt++;
} bool dfs(int u){
used[u] = true;
for(int i = head[u]; ~i; i = edge[i].next){
int v = edge[i].to, w = match[v];
if(w < 0 || !used[w] && dfs(w)){
match[u] = v;
match[v] = u;
return true;
}
}
return false;
} void dfs1(int u){
visx[u] = 1;
for(int i = head[u]; ~i; i = edge[i].next){
int v = edge[i].to;
if(visy[v]) continue;
visy[v] = 1;
dfs1(match[v]);
}
} int main(){
int r, c;
while(scanf("%d %d %d", &r, &c, &m) == 3 && r+c+m){
ms(head, -1); cnt = 0;
for(int i = 0; i < m; ++i){
int u, v;
scanf("%d %d", &u, &v);
--u, --v;
addEdge(u, v + r);
}
n = r + c;
ms(match, -1);
int ans = 0;
for(int i = 0; i < n; ++i) if(match[i] < 0){
ms(used, 0); if(dfs(i)) ++ans;
}
printf("%d", ans);
ms(visx, 0); ms(visy, 0);
ms(used, 0);
for(int i = 0; i < r; ++i) if(match[i] != -1) used[i] = 1;
for(int i = 0; i < r; ++i) if(!used[i]) dfs1(i);
for(int i = 0; i < r; ++i) if(!visx[i]) printf(" r%d", i + 1);
for(int i = r; i < n; ++i) if(visy[i]) printf(" c%d", i + 1 - r);
printf("\n");
}
return 0;
}

  

UVa 11419 SAM I AM (最小覆盖数)的更多相关文章

  1. UVA 11419 SAM I AM (最小点覆盖,匈牙利算法)

    题意:给一个r*c的矩阵,某些格子中可能有一些怪物,可以在一行或一列防止一枚大炮,大炮会扫光整行/列的怪,问最少需要多少炮?输出炮的位置. 思路: 先每行和列都放一个炮,把炮当成点,把怪当成边,一边连 ...

  2. UVA 11419 SAM I AM(最大二分匹配&最小点覆盖:König定理)

    题意:在方格图上打小怪,每次可以清除一整行或一整列的小怪,问最少的步数是多少,又应该在哪些位置操作(对输出顺序没有要求). 分析:最小覆盖问题 这是一种在方格图上建立的模型:令S集表示“行”,T集表示 ...

  3. Uva - 11419 - SAM I AM

    题意:一个矩形——R*C的网格,在某些位置上有石头,在网格外开一炮可以打掉该行或者该列的石头,求打掉这些石头最少需要多少门大炮,位置分别设在哪行哪列(0<R<1001, 0 < C ...

  4. 训练指南 UVA - 11419(二分图最小覆盖数)

    layout: post title: 训练指南 UVA - 11419(二分图最小覆盖数) author: "luowentaoaa" catalog: true mathjax ...

  5. SAM I AM UVA - 11419 最小点集覆盖 要输出具体覆盖的行和列。

    /** 题目:SAM I AM UVA - 11419 链接:https://vjudge.net/problem/UVA-11419 题意:给定n*n的矩阵,'X'表示障碍物,'.'表示空格;你有一 ...

  6. POJ 3041 Asteroids 最小覆盖数

    http://poj.org/problem?id=3041 题目大意: 一辆宇宙飞船在一个小行星带中,你知道,这很危险.他有一种武器,可以清除掉一行或一列的小行星.问把小行星全部清除最少的武器使用次 ...

  7. UVa 11419 我是SAM(最小点覆盖+路径输出)

    https://vjudge.net/problem/UVA-11419 题意:一个网格里面有一些目标,可以从某一行,某一列发射一发子弹,可以打掉它:求最少的子弹,和在哪里打? 思路: 每个点的x坐标 ...

  8. SAM I AM UVA - 11419(最小顶点覆盖+输出一组解)

    就是棋盘问题输出一组解 https://blog.csdn.net/llx523113241/article/details/47759745 http://www.matrix67.com/blog ...

  9. Uva 11419 我是SAM

    题目链接:https://vjudge.net/problem/UVA-11419 题意:一个网格里面有一些目标,可以从某一行,某一列发射一发子弹,可以打穿: 求最少的子弹,和在哪里打? 分析: 听说 ...

随机推荐

  1. sublime text 3 配置优化

    1.在用Sublime里编写代码时,需要把TAB键转换成四个空格. 菜单栏里点击:首选项-> 设置-用户(Preferences-> Setting-User)在弹出来的文本里,添加如下两 ...

  2. CCFlow工作流程起航

    详细可参考SDK请假流程.但请假流程中定义的四个表单只是四个节点表单,首先要依靠访问指向这个请假流程,两种方法进入: 一.是在流程设计中点击运行: 二.先访问 WF\App\Simple\login. ...

  3. C# List的深复制

    1.关于深拷贝和浅拷贝 C#支持两种类型:值类型和引用类型 值类型(Value Type):如 char, int, float,枚举类型和结构类型 引用类型(Reference Type):如Cla ...

  4. C BIN加密

    #include <stdio.h> #include <string.h> #include <stdlib.h> #ifndef DWORD #define D ...

  5. 关于layoutparam 请铭记。。。。

    //rl_pager 是RelativeLayout findViewById(R.id.rl_pager).setLayoutParams(new RelativeLayout.LayoutPara ...

  6. bzoj 3615: MSS

    Description 小C正在出一道题...因为语文水平有限他想不出复杂的背景,所以以下就是题意了. 平面上有N个点,开始时每个点属于一个不同的集合.不妨设点Pi属于集合Si.请维护数据结构支持以下 ...

  7. Appium使用ID进行定位

      1 使用uiautomatorviewer地获取元素ID 路径:sdk\tools\uiautomatorviewer.bat 2 脚本中增加点击事件 driver.find_element_by ...

  8. 认识Linux操作系统

    Linux系统是一个类似UNIX的操作系统 认识Linux的来世与今生 1.Linux系统的历史 Linux系统是一个类似UNIX的操作系统,Linux系统是UNIX在微机上的完整实现,它的标志是一个 ...

  9. 二货Mysql中设置字段的默认值问题

    Mysql设置字段的默认值的确很落伍 1.不支持函数 2.只支持固定常量. 经常用到的日期类型,因为不支持getdate或者now函数,所以只能设置timestamp类型 而且还必须在默认值那个地方写 ...

  10. MySQL转Oracle,MyBatis Mapper XML 文件修改项总结

    1.对于批量插入 需要更改成 <insert id="saveAll"> insert into(a,b,c) <foreach collection=" ...