当前位置: 首页 > news >正文

HDU-1045 Fire Net(简单缩点+最大匹配)

题意:

给出n(<=4),然后n行n列点,'X'代表墙,'.'代表空地,现需要往图中的空地放一些炮楼,两个炮楼不能同时在同一行或者同一列除非两个炮楼之间存在墙。求最大放置炮楼的数量。

思路:

刚开始尝试最大独立集,但是互相限制的点构图构不成二分图,尝试直接最大匹配也是构不成二分图。然后看到别人思路发现可以进行缩点,即在一行或一列若干个空地构成一个大空地,显然这若干个点中最多只能放一个点,所以进行按行分区和按列分区,两种分区分别都是包括了全部空地的划分(注意是分别而非一起)。

那么每个行连通块确保了该块内只选择一个,而与其相交的列连通块则表示选择当前行连通块的某一块空地的同时必须也要选择该块空地连带的列连通块,则这样就符合了二分图中边的性质了,从而我们对构造的二分图求最大匹配就是答案了。


代码:

#include <algorithm>
#include <iostream>
#include <string.h>
#include <cstdio>
#include <vector>
using namespace std;
char mp[5][5];
int g[25][25];
int n, cnt, ans;
int match[25], vis[25];
vector<int> bl[25][2];
int use[25][2];
int dfs(int cur)
{
	for(int i = 0; i <= cnt; ++i)
	{
		if(!g[cur][i] || vis[i]) continue;
		vis[i] = 1;
		if(match[i] == -1 || dfs(match[i]))
		{
			match[i] = cur;
			return 1;
		}
	}
	return 0;
}
int main()
{
	while(~scanf("%d", &n) && n)
	{
		memset(g, 0, sizeof g); cnt = 0;
		memset(match, -1, sizeof match);
		memset(use, 0, sizeof use);
		for(int i = 0; i < n*n; ++i) bl[i][0].clear(), bl[i][1].clear();
		for(int i = 0; i < n; ++i) scanf("%s", mp[i]);
		for(int i = 0; i < n; ++i)
		for(int j = 0; j < n; ++j)
		{
			if(mp[i][j] == 'X') continue;
			if(!use[i*n+j][0])
			{
				int k = i; ++cnt;
				while(k < n && mp[k][j] == '.')
				{
					use[k*n+j][0] = 1;
					bl[k*n+j][0].push_back(cnt);
					++k;
				}
			}
			if(!use[i*n+j][1])
			{
				int k = j; ++cnt;
				while(k < n && mp[i][k] == '.')
				{
					use[i*n+k][1] = 1;
					bl[i*n+k][1].push_back(cnt);
					++k;
				}
			}
		}
		for(int i = 0; i < n; ++i)
		for(int j = 0; j < n; ++j)
		{
			int k = i*n+j;
			for(int ii = 0; ii < bl[k][0].size(); ++ii)
			for(int jj = 0; jj < bl[k][1].size(); ++jj)
			{
				g[bl[k][0][ii]][bl[k][1][jj]] = 1;
				g[bl[k][1][jj]][bl[k][0][ii]] = 1;
			}
		}
		ans = 0;
		for(int i = 1; i <= cnt; ++i)
		{
			memset(vis, 0, sizeof vis);
			if(dfs(i)) ++ans;
		}
		printf("%d\n", ans/2);
	}
	return 0;
}


继续加油~

相关文章:

  • python 文件与目录的操作   未完善 需要重新学习
  • LightOJ-1296 Again Stone Game(SG打表找规律)
  • ejb3中的@Schedule中的persistent属性的深入探索
  • HDU-2389 Rain on your Parade(二分图之Hopcroft-Karp算法)
  • javascript实现 color颜色格式转换【 rgb和十六进制的转换】
  • HDU-4686 Arc of Dream(推公式+矩阵快速幂)
  • python之测试
  • Codeforces-557D Vitaly and Cycle(二分图染色)
  • POJ-1019 Number Sequence(思维题)
  • 【吾日三省吾身】2015.6.13-涅槃行动第二十六天
  • Codeforces Round #427 (Div. 2)-C. Star sky(二维前缀和)
  • sequioadb源码分析2
  • HDU-6058 Kanade's sum - 2017 Multi-University Training Contest - Team 3(思维+模拟链表)
  • PowerShell获取特定“描述”的虚拟机IP地址
  • HDU-6060 RXD and dividing - 2017 Multi-University Training Contest - Team 3(思维+最小斯坦纳树)
  • [微信小程序] 使用ES6特性Class后出现编译异常
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • C++11: atomic 头文件
  • Java方法详解
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • js算法-归并排序(merge_sort)
  • session共享问题解决方案
  • SpiderData 2019年2月23日 DApp数据排行榜
  • Vue 动态创建 component
  • 蓝海存储开关机注意事项总结
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • ​批处理文件中的errorlevel用法
  • #LLM入门|Prompt#3.3_存储_Memory
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (2)STM32单片机上位机
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (第61天)多租户架构(CDB/PDB)
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (生成器)yield与(迭代器)generator
  • (原)Matlab的svmtrain和svmclassify
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • ***测试-HTTP方法
  • .NET 8.0 发布到 IIS
  • .NET Core 通过 Ef Core 操作 Mysql
  • .net oracle 连接超时_Mysql连接数据库异常汇总【必收藏】
  • .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .NET上SQLite的连接
  • /usr/local/nginx/logs/nginx.pid failed (2: No such file or directory)
  • @Async注解的坑,小心
  • @Autowired注解的实现原理
  • @GlobalLock注解作用与原理解析
  • @取消转义
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(白虎组)
  • [android] 手机卫士黑名单功能(ListView优化)
  • [C#]winform使用引导APSF和梯度自适应卷积增强夜间雾图像的可见性算法实现夜间雾霾图像的可见度增强
  • [CTO札记]如何测试用户接受度?
  • [EMWIN]FRAMEWIN 与 WINDOW 的使用注意