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

题目就转化为:有 \(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. [题解] [LOJ2743]「JOI Open 2016」摩天大楼

    题目大意 将 \(N\) 个互不相同的整数 \(A_1 , A_2 , ⋯ , A_N\) 任意排列成 \(B_1 , B_2 , ⋯ , B_N\) . 要求 \(∑^{N−1}_{i=1} |B_ ...

  2. typeScript类型总结

    1.对象类型 {} 用来指定对象中可以包含哪些属性,在属性名后加?表示属性是可选的 语法:{属性名:属性值类型,属性名:属性值类型} 示例: let a:{name:string,age?:numbe ...

  3. range内部代码

    def my_range(a, b=None, c=1): if not b: b = a a = 0 while a < b: yield a a += c

  4. 操作系统实现-printk

    博客网址:www.shicoder.top 微信:18223081347 欢迎加群聊天 :452380935 这一次我们来实现最基础,也是最常见的函数print,大家都知道这个是可变参数函数,那具体怎 ...

  5. FinClip小程序+Rust(三):一个加密钱包

    ​ 一个加密货币钱包,主要依赖加密算法构建.这部分逻辑无关iOS还是Android,特别适合用Rust去实现.我们看看如何实现一个生成一个模拟钱包,准备供小程序开发采用 前言 在之前的内容我们介绍了整 ...

  6. Angular核心概念

    一.集成开发环境@angular/cli IE8之后才有debugger工具 2009,nodejs发布,前端Big Bang 1.1 基于NodeJS的工具链 打包工具 grunt 对js代码做合并 ...

  7. unity---脚本代码报错

    同版本编辑器在不同VS版本下会报错问题解决 解决方法 报错情况 解决方法 打开Unity --->Preferences--->External Tools然后点击:Regenerate ...

  8. unity---3D数学基础

    点乘 A·B 判断敌人在前方还是后方 调试画线 画线段 前两个参数 分别是 起点 终点 画射线 前两个参数 分别是 起点 方向 Debug.DrawLine(this.transform.positi ...

  9. OpenHarmony3.1 Release版本特性解析——硬件资源池化架构介绍

    李刚 OpenHarmony 分布式硬件管理 SIG 成员 华为技术有限公司分布式硬件专家 OpenHarmony 作为面向全场景.全连接.全智能时代的分布式操作系统,通过将各类不同终端设备的能力进行 ...

  10. 没错,就是Access-Control-Allow-Origin,跨域

    服务端添加: <add name="Access-Control-Allow-Origin" value="*" /><add name=&q ...