弱化一下,先考虑在二维上解决问题。

题目就转化为:有 \(n\) 个点 \((i, j)\) 需要被覆盖,而我们每次可以选一行或一列去覆盖,求覆盖所有点的最少选择次数。

如果我们对于每一个 \((i, j)\),我们把第 \(i\) 行和第 \(j\) 列连边,显然能构成一张二分图。

图中每一条边就是一个需求,而每选择一个点就能解决掉所有与之相连的需求,答案就是解决所有需求最少需要选择的点数。这就是二分图上的最小点覆盖问题。

答案即为最大匹配数。

现在加入三维。因为 \(a, b, c \leq 5 \times 10 ^ 3\),所以 \(\min \{ a, b, c \} \leq 13\)。

那么我们可以考虑用最多 \(2^{13}\) 的时间去枚举其中一维的选择,即枚举这一维上我们选择哪几条基准线先直接覆盖。

那么剩下的就是之前的二维做法了。注意每次枚举的时候应该枚举最小的那一位,这样才能保证复杂度。

二分图最大匹配使用匈牙利算法,在接近完全图的图中性能相比于 Dinic 会较好。

#include <cstdio>

int Abs(int x) { return x < 0 ? -x : x; }
int Max(int x, int y) { return x > y ? x : y; }
int Min(int x, int y) { return x < y ? x : y; } int read() {
int x = 0, k = 1;
char s = getchar();
while(s < '0' || s > '9') {
if(s == '-')
k = -1;
s = getchar();
}
while('0' <= s && s <= '9') {
x = (x << 3) + (x << 1) + (s ^ 48);
s = getchar();
}
return x * k;
} void write(int x) {
if(x < 0) {
x = -x;
putchar('-');
}
if(x > 9)
write(x / 10);
putchar(x % 10 + '0');
} void print(int x, char s) {
write(x);
putchar(s);
} const int MAXN = 5e3 + 5;
const int MAXM = 2e5 + 5;
const int MAXL = 5e3 + 5;
const int INF = 2147483647; struct edge {
int v, w, nxt;
edge() {}
edge(int V, int W, int Nxt) {
v = V, w = W, nxt = Nxt;
}
} e[MAXM << 1];
int head[MAXN], n, m, cnt;
void Add_Edge(int u, int v, int w) {
e[cnt] = edge(v, w, head[u]);
head[u] = cnt++;
}
bool Chose[MAXM << 1];
int Mat[MAXN], Tim[MAXN], tot; void init(int N, int M) {
for(int i = 0; i <= cnt; i++)
Chose[i] = false;
n = N, m = M;
for(int i = 1; i <= n; i++)
head[i] = -1, Tim[i] = 0, Mat[i] = 0;
cnt = 0, tot = 0;
} bool dfs(int u) {
if (Tim[u] == tot)
return false;
Tim[u] = tot;
for (int i = head[u], v; ~i; i = e[i].nxt) {
if(Chose[e[i].w])
continue;
v = e[i].v;
if (!Mat[v] || dfs(Mat[v])) {
Mat[v] = u;
return true;
}
}
return false;
} int calc() {
int ans = 0;
for (int i = 1; i <= m; i++)
Mat[i] = 0;
for (int i = 1; i <= n; i++)
Tim[i] = 0;
for (int i = n; i >= 1; i--) {
tot++;
ans += dfs(i);
}
return ans;
} bool vis[MAXN];
int q[MAXN], pos[5], len = 0, ans = INF, tot2 = 0, S, T; void dfs2(int p) {
if(p > pos[1]) {
ans = Min(ans, calc() + tot2);
return ;
}
Chose[p] = true;
tot2++;
dfs2(p + 1);
Chose[p] = false;
tot2--;
dfs2(p + 1);
} int main() {
int t = read();
while(t--) {
for(int i = 1; i <= 3; i++)
pos[i] = read();
if(pos[1] > pos[2])
pos[1] ^= pos[2] ^= pos[1] ^= pos[2];
if(pos[2] > pos[3])
pos[2] ^= pos[3] ^= pos[2] ^= pos[3];
if(pos[1] > pos[2])
pos[1] ^= pos[2] ^= pos[1] ^= pos[2];
init(pos[2], pos[3]);
len = 0, ans = INF, tot = 0;
for(int i = 1, j, k, p; i <= pos[1]; i++)
for(j = 1; j <= pos[2]; j++)
for(k = 1; k <= pos[3]; k++) {
p = (i - 1) * pos[2] * pos[3] + (j - 1) * pos[3] + k;
q[p] = read();
if(q[p])
Add_Edge(j, k, i);
}
dfs2(1);
print(ans, '\n');
}
return 0;
}

Solution -「HNOI2013」消毒的更多相关文章

  1. 「HNOI2013」游走

    「HNOI2013」游走 题目描述 一个无向连通图,顶点从 \(1\) 编号到 \(N\) ,边从 \(1\) 编号到 \(M\) .小 \(Z\) 在该图上进行随机游走,初始时小 \(Z\) 在 \ ...

  2. 「题解」「HNOI2013」切糕

    文章目录 「题解」「HNOI2013」切糕 题目描述 思路分析及代码 题目分析 题解及代码 「题解」「HNOI2013」切糕 题目描述 点这里 思路分析及代码 题目分析 这道题的题目可以说得上是史上最 ...

  3. Solution -「构造」专练

    记录全思路过程和正解分析.全思路过程很 navie,不过很下饭不是嘛.会持续更新的(应该). 「CF1521E」Nastia and a Beautiful Matrix Thought. 要把所有数 ...

  4. Solution -「原创」Destiny

    题目背景 题目背景与题目描述无关.签到愉快. 「冷」 他半靠在床沿,一缕感伤在透亮的眼眸间荡漾. 冷见惆怅而四散逃去.经历嘈杂喧嚣,感官早已麻木.冷又见空洞而乘隙而入.从里向外,这不是感官的范畴. 他 ...

  5. Solution -「GLR-R2」教材运送

    \(\mathcal{Description}\)   Link.   给定一棵包含 \(n\) 个点,有点权和边权的树.设当前位置 \(s\)(初始时 \(s=1\)),每次在 \(n\) 个结点内 ...

  6. 「HNOI2013」切糕

    题目链接 戳我 \(Solution\) 对于这道题,我们首先来看看没有\(D\)这个约束的该如何做. 我们考虑构造最小割模型. 其实直接贪心就好了,选出每条路径上的最小值就好了(路径就是将每层的同一 ...

  7. Solution -「WF2011」「BZOJ #3963」MachineWorks

    \(\mathcal{Description}\)   Link.   给定你初始拥有的钱数 \(C\) 以及 \(N\) 台机器的属性,第 \(i\) 台有属性 \((d_i,p_i,r_i,g_i ...

  8. Solution -「LOCAL」二进制的世界

    \(\mathcal{Description}\)   OurOJ.   给定序列 \(\{a_n\}\) 和一个二元运算 \(\operatorname{op}\in\{\operatorname{ ...

  9. Solution -「SHOI2016」「洛谷 P4336」黑暗前的幻想乡

    \(\mathcal{Description}\)   link.   有一个 \(n\) 个结点的无向图,给定 \(n-1\) 组边集,求从每组边集选出恰一条边最终构成树的方案树.对 \(10^9+ ...

随机推荐

  1. Python最强IDE(PyCharm)安装教程

    欢迎关注公众号[Python开发实战],免费领取Python学习电子书! PyCharm是目前最流行.使用最广泛的Python IDE(Integrated Development Environme ...

  2. Go语言学习——map

    map 映射关系容器 内部使用散列表(hash)实现 map是引用类型 必须初始化才能使用 无序的基于key-value的数据结构 map定义 map的定义语法: map[KeyType]ValueT ...

  3. 1.sprng 简介

    容器(可以用来管理所有的组件(类)) 核心关注:IOC和AOP 1.IOC Inversion(反转) Of Control:控制反转 控制:资源的获取方式 1.主动式(要什么资源自己创建) Pers ...

  4. 虚拟机中CentOS-7.9的硬盘空间扩容(EXSI)

    目录 一.增加虚机容量 二.创建新的分区 三.格式化新分区 四.lvm实现卷扩容 五.文件系统的扩容 大家好,我是LSF,发现一台虚机上 /dev/mapper/centos-root Use%已经快 ...

  5. ElasticSearch7.3学习(二十四)----相关度评分机制详解

    1.算法介绍 relevance score(相关性分数) 算法,简单来说,就是计算出,一个索引中的文本,与搜索文本,他们之间的关联匹配程度.Elasticsearch使用的是 term freque ...

  6. kali linux安装后乱码的解决方法

    操作系统是5.3 解决方法是在终端执行命令: sudo apt-get install ttf-wqy-zenhei

  7. Springboot启动类及注解说明

    Spring boot的启动是基于main方法的,其主要注解为: 1. @springBootApplication:项目的启动注解,是一个组合注解,包含@SpringbootConfiguratio ...

  8. linux篇-centos7搭建apache服务器(亲测可用)

    1安装apache yum install httpd httpd-devel -y 2开启服务器 systemctl start httpd.service 3开机自启 systemctl enab ...

  9. net core天马行空系列-可用于依赖注入的,数据库表和c#实体类互相转换的接口实现

    1.前言 hi,大家好,我是三合.作为一名程序猿,日常开发中,我们在接到需求以后,一般都会先构思一个模型,然后根据模型写实体类,写完实体类后在数据库里建表,接着进行增删改查, 也有第二种情况,就是有些 ...

  10. php 图片转换二进制数

    $image = "1.jpg"; //图片地址 $fp = fopen($image, 'rb'); $content = fread($fp, filesize($image) ...