[HNOI2013]消毒

题目

https://www.luogu.org/problemnew/show/P3231

思路

首先考虑二维
在这里插入图片描述

显然,这么染是最佳的
在这里插入图片描述

所以我们建立二分图,对于每个黑色块 (x,y)(x,y),我们将其处于第一部的 xx 与处于第二部的 yy 连接,求一个最小点覆盖。二分图中最小点覆盖=最大匹配,就得到了答案。

而现在是三维
看到题目中有abc<=5000a∗b∗c<=5000,也就意味着a,b,ca,b,c中至少有一个不大于1717。所以就先暴搜对应的轴上的不大于1717个面是否被操作(对应的面上的所有点被消除),然后求最小点覆盖来更新答案。

代码

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int T, list[5005], cnt, a, b, c, minn, sx[4][5005], uu, ans, lnk[5005], qaq;
bool qwq[25], vis[5005];
struct e{
	int to, next;
}e[5005];
void add(int fro, int to){
	e[++cnt].next = list[fro];
	e[cnt].to = to;
	list[fro] = cnt;
}
bool dfs(int x){
	for(int i=list[x]; i; i=e[i].next){
		int t=e[i].to;
		if(!vis[t]){
			vis[t] = true;
			if(!lnk[t] || dfs(lnk[t])){
				lnk[t] = x;
				return true;
			}
		}
	}
	return false;
}
void work(int x){
	for(int i=1; i<=b; i++)	list[i] = 0;
	cnt = 0;
	for(int i=1; i<=c; i++)	lnk[i] = 0;
	int tmp=0;
	for(int i=0; i<a; i++){
		if(x&(1<<i))	qwq[i+1] = false, tmp++;
		else	qwq[i+1] = true;
	}
	for(int i=1; i<=qaq; i++)
		if(qwq[sx[1][i]])
			add(sx[2][i], sx[3][i]);
	for(int i=1; i<=b; i++){
		for(int j=1; j<=c; j++)	vis[j] = false;
		if(dfs(i))	tmp++;
	}
	ans = min(tmp, ans);
}
int main(){
	cin>>T;
	while(T--)
	{
		qaq = 0;
		ans = 0x3f3f3f3f;
		scanf("%d%d%d", &a, &b, &c);
		minn = min(a, min(b, c));
		for(int i=1; i<=a; i++)
			for(int j=1; j<=b; j++)
				for(int k=1; k<=c; k++)
				{
					scanf("%d", &uu);
					if(!uu)	continue;
					sx[1][++qaq] = i;
					sx[2][qaq] = j;
					sx[3][qaq] = k;
				}
		if(minn==b)	swap(a, b), swap(sx[1], sx[2]);
		else if(minn==c) swap(a, c), swap(sx[1], sx[3]);
		for(int i=0; i<(1<<a); i++) work(i);
		printf("%d\n", ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值