【POJ3740】Easy Finding DLX(Dancing Links)精确覆盖问题

精确覆盖问题、Algorithm X 与 Dancing Links(DLX) 精确覆盖(Exact Cover)问题 精确覆盖 S 为集合 X 的若干个子集构成的集合,若存在 S 的一个子集 S*,满足 X 中的元素有且只有一次包含在 S* 的一个元素中,那么称 S* 为 X 的一个精确覆盖。 S*属性 根据定义 S* 具有以下属性: 1. S* 中任意两个元素交集为空。 2. S* 中所有元素并集为 X。 例子 假定 S = { A, B, C 阅读详情

题意:多组数据,每组数据给你几行数,要求选出其中几行,使得每一列都有且仅有一个1,询问是可不可行,或者说能不能找出来。

题解:1、暴搜。2、DLX(Dancing links)。

本文写的是DLX。算法参考白书P406或者http://www.cnblogs.com/grenet/p/3145800.html

我说一些细致的东西,就是删除操作的形状是

    |

——|————

——|————

——|————

被删除的点们之间的联系不用删,可以保留。准确地说它并不是删去了这些点,而是删去这个形。

而且恢复时要反着恢复。

首先先确定从哪一列删除,进行一次remove,然后枚举这一列的每一行,对其进行remove,然后dfs,然后再resume。跳出循环时再resume确定列。

附代码,应该很好看,只要略耐心 一点点点点点。。我保证绝对比网上其他人的可读性强。

哦,对了,并不需要写点、行、列的单独的remove和resume函数,那太傻了,写模板也不需要,我想这应该永远用不上的。。。。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 400
#define NN 10000
using namespace std;
struct DLX
{
	int U[NN],D[NN],L[NN],R[NN],C[NN];
	int H[NN],T[NN],cnt;
	inline void init(int m)
	{
		cnt=0;
		memset(H,0,sizeof(H));
		for(cnt=0;cnt<=m;cnt++)
		{
			U[cnt]=D[cnt]=C[cnt]=cnt;
			L[cnt]=cnt-1,R[cnt]=cnt+1;
		}
		L[0]=--cnt,R[cnt]=0;
	}
	inline void newnode(int x,int y)
	{
		C[++cnt]=y;T[y]++;

		if(!H[x])H[x]=L[cnt]=R[cnt]=cnt;
		else L[cnt]=H[x],R[cnt]=R[H[x]];
		R[H[x]]=L[R[H[x]]]=cnt,H[x]=cnt;

		U[cnt]=U[y],D[cnt]=y;
		U[y]=D[U[y]]=cnt;
	}
	inline void scan(int n,int m)
	{
		int i,j,k;
		for(i=1;i<=n;i++)for(j=1;j<=m;j++)
		{
			scanf("%d",&k);
			if(k)newnode(i,j);
		}
	}
	inline void remove(int x)
	{
		for(int i=D[x];i!=x;i=D[i])
		{
			for(int j=R[i];j!=i;j=R[j])
			{
				U[D[j]]=U[j];
				D[U[j]]=D[j];
				T[C[j]]--;
			}
		}
		L[R[x]]=L[x];
		R[L[x]]=R[x];
	}
	inline void resume(int x)
	{
		for(int i=U[x];i!=x;i=U[i])
		{
			for(int j=L[i];j!=i;j=L[j])
			{
				U[D[j]]=j;
				D[U[j]]=j;
				T[C[j]]++;
			}
		}
		L[R[x]]=x;
		R[L[x]]=x;
	}
	inline bool dfs()
	{
		if(!R[0])return true;
		int S=R[0],W=T[S],i,j;
		for(i=R[S];i;i=R[i])if(T[i]<W)
		{
			W=T[i];
			S=i;
		}
		remove(S);
		for(i=D[S];i!=S;i=D[i])
		{
			for(j=R[i];j!=i;j=R[j])remove(C[j]);
			if(dfs())return true;
			for(j=L[i];j!=i;j=L[j])resume(C[j]);
		}
		resume(S);
		return false;
	}
}dlx;
int main()
{
//	freopen("test.in","r",stdin);
//	freopen("my.out","w",stdout);
	int n,m;
	while(~scanf("%d%d",&n,&m))
	{
		dlx.init(m);
		dlx.scan(n,m);
		if(dlx.dfs())puts("Yes, I found it");
		else puts("It is impossible");
	}
	return 0;
}

给点福利。

专属那些输出调试者。

	inline void print_line(int x)
	{
		int i=x;
		do{
			printf("%d->",i);
			i=R[i];
		}while(i!=x);
		puts("");
	}
	inline void print_list(int x)
	{
		int i=x;
		do{
			printf("%d->",i);
			i=D[i];
		}while(i!=x);
		puts("");
	}
	inline void print(int x)
	{
		int i=x;
		do{
			print_list(i);
			puts("|");
			i=R[i];
		}while(i!=x);
		puts("");
		puts("");
	}

当然,你非得点行列写单独操作我也不拦你。

        inline void remove_point(int x)
	{
		D[U[x]]=D[x];
		U[D[x]]=U[x];
		R[L[x]]=R[x];
		L[R[x]]=L[x];
	}
	inline void resume_point(int x)
	{
		D[U[x]]=x;
		U[D[x]]=x;
		R[L[x]]=x;
		L[R[x]]=x;
	}
	inline void remove_line(int x)
	{
		int i=x;
		do{
			U[D[i]]=U[i];
			D[U[i]]=D[i];
			i=R[i];
		}while(i!=x);
	}
	inline void resume_line(int x)
	{
		int i=x;
		do{
			U[D[i]]=i;
			D[U[i]]=i;
			i=L[i];
		}while(i!=x);
	}
	inline void remove_list(int x)
	{
		int i=x;
		do{
			R[L[i]]=R[i];
			L[R[i]]=L[i];
			i=D[i];
		}while(i!=x);
	}
	inline void resume_list(int x)
	{
		int i=x;
		do{
			R[L[i]]=i;
			L[R[i]]=i;
			i=U[i];
		}while(i!=x);
	}

然后数据我就不贴了,直接去看3740discuss吧,有两组。


避坑指南:WSL2网络模式修改导致无法上网的解决方案(附备份还原技巧) 本文深入解析WSL2默认网络隔离机制,并提供三种安全的端口互通方案,重点推荐通过配置Windows防火墙规则实现稳定访问。同时,针对网络配置修改可能引发的无法上网问题,给出了从重置配置到系统级备份的完整恢复指南,确保开发环境安全可靠。 阅读详情

相关推荐

Unity 实现动态网格地图生成与交互组件

本文详细介绍了在Unity中实现动态网格地图生成与交互组件的完整方案。从基础网格单元实现到高级交互功能,涵盖网格生成器核心逻辑、事件驱动架构、性能优化技巧以及六边形网格等特殊实现。特别适合游戏开发者学习如何构建战棋、模拟经营类游戏的可交互地图系统,提升开发效率与用户体验。

weixin_29015483的博客 1068

精确覆盖问题的回溯算法(一)——问题描述

一、问题描述 精确覆盖问题(Exact Cover Problem),是指给定了一个全集S以及它的m个子集S1、S2、..Sm以后,要求出一组子集,使这组子集的并等于原来的全集S,且各子集两两不交。 例:设 S={1,2,3,4,5,6,7}, A={1,4,7}, B={1,4}, C={4,5,7}, D={3,5,6}, E={2,3,6,7} ,F={2,7} 则子集组

laomai的专栏 3719

EXCEL VBA 导出高清图片方法

EXCEL VBA 导出高清图片方法 将EXCEL表格内容另存为图片的方法有很多种,简单的比如“复制为图片格式并另存”,“打印成XPS”等等,本文着重的是利用VBA实现的方法。 该方法适合用于中大型图文表格输出为图片格式,方便传阅,在office2010及以上版本最为流畅。 具体看代码: Sub printA4() Dim rng As Range '定义截图范围变量 'm = 20...

nfser_burn7的专栏 1万+

dancing links(舞蹈链)——求解精准覆盖及重复覆盖问题

跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 例如:如下的矩阵 就包含了这样一个集合(第1、4、5行) 如何利用给定的矩阵求出相应的行的集合呢?我们采用回溯法 矩阵1: 先假定选择第1行,如下所示: 如上图中所示,红色的那行是选中的一行,这一行...

ling_wang的博客 2704

Qt 【window udp 高频采集丢包问题】

使用Asio + 无锁队列或者环形缓存区方案可以解决 qt udp 在window平台高速采集 (128k)丢包问题。

weixin_45397344的博客 177

【优化模型】求解混合整数线性规划 MILP 问题

混合整数线性规划(Mixed Integer Linear Programming,MILP)是一类优化问题,其中目标函数和约束条件均为线性,并且包含整数变量。MILP 在实际应用中具有广泛的应用,可以解决很多实际问题,如生产调度、网络设计、资源分配等。f — 系数向量。系数向量,指定为实数向量或实数数组。intcon — 整数约束组成的向量。整数约束组成的向量,指定为正整数向量。intcon 中的值指示决策变量 x 中应取整数值的分量。A — 线性不等式约束。线性不等式约束,指定为实矩阵。

Fanjufei的博客 2497

DLX精确覆盖

DLX精确覆盖:对于给定的01矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 数独转换为DLX精确覆盖求解: 每个格子都要填入数字---001到081列,表示数独中9*9=81个格子是否填入数字。如果是,则选取的行在该列上为1。 每一行都要有1~9填入---082到162列,每9列就代表数独中的一行,如果该行有某个数字,则其对应的列上为1 每一列都要有1~9填入---163到243...

maze_illusion的博客 489

【大模型】DeepSeek + Coze 打造个人专属AI智能体使用详解

DeepSeek + Coze 打造个人专属AI智能体使用详解

congge 1万+

精确覆盖问题

精确覆盖问题(Exact Cover Problem),指给定许多集合Si(1≤i≤n)S_i\left(1\le i\le n\right)Si​(1≤i≤n), 以及集合X⊂SX\subset SX⊂S,求满足以下条件的无序多元组(T1,T2,⋯ ,Tm)\left(T_1,T_2,\cdots,T_m\right)(T1​,T2​,⋯,Tm​):(001011010010010110010100100001000010001101) \left(\begin{array}{lllllll} 0 & 0

思维缜密的博客 1485

模组 RG500Q入网问题分析

- [ ] 不同于公网,在5G专网环境中, 通常使用很多非标准的网络配置,如PLMN/APN等。因此,5G模组在专网环境下通常要做一些专门的配置才能正常入网,本文分析一例在专网环境, 5G终端无法入网问题的定位过程。 - [ ] 具体涉及到以下模组操作: 恢复出厂、SA only、锁BAND、配置MBN等

十年通信老兵的技术修炼之路——从3G到5G,从地面基站到卫星通信。 935

Ultralytics 框架中 model.predict() 返回的 results 对象的详细解析

通过掌握 results 对象的使用方法,您可以快速实现模型部署、数据分析与可视化。

浩瀚之水的专栏 748

DLX精确覆盖问题

铃兰小姐邀请您来一起学习舞蹈~链算法!快点进来和铃兰一起学习吧!

GROZAX的博客 472

Ardupilot无人船(车)mavros自主控制

rover 4.4。

超维空间科技的博客 3229

POJ 3740 Easy Finding(DLX精确覆盖裸题)

POJ 3740 Easy Finding 题目链接 题意:选一些行,要求每行正好覆盖一个列 思路:精确覆盖裸题 代码: #include #include using namespace std; const int MAXNODE = 500010; const int MAXN = 510; const int MAXM = 1010; const i

Remilia's 867

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Easy Finding POJ - 3740 (DLX)

显然这是一道dfs简单题 或许匹配也能做 然而用了dancing links 显然这也是一道模板题 好的吧 调了一上午 终于弄好了模板 Easy Finding Time Limit:1000MS Memory Limit:65536K Total Submissions:19052 Accepted:5273 De...

weixin_30532759的博客 83

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

POJ 3740 Easy Finding 位运算压缩+DFS or Dancing Links

Easy Finding 这道题运用二进制DFS是比较好的方法,当然还可以用dancing links,这个比较高级,先把我看别人的二进制思路然后写的代码贴上来。 当然本题是体现不出DLX的高级之处的。用位运算和DLX的速度应该是相当 /* ID: sdj22251 PROG: calfflac LANG: C++ */ #include #include #include #in

水 966

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

POJ3740 Easy Finding - Dancing Links

DLX的模板题。精确覆盖问题。 给你一个01矩阵,现在选择几行,是每列有且只有一个1. 操作过程不难理解。。就是建图坑了一会。。这次吃了大亏了 Easy Finding Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14686   Accepted: 3841

600

POJ3740Easy Finding(DLX入门)

->题目请戳这里 题目大意:给一个m*n的01矩阵,求是否存在若干行,使这些行中的1覆盖所有的列恰好1次。 题目分析:裸的精确覆盖题目,建图+模版= AC。需要用到dance links这种数据结构优化。dancing links也是最近才学,今天刚弄明白,这此特别感谢yyd大牛,帮我解决了一个小瓶颈。 关于dancing links,仔细研究才能发现dancing lingks是如此绝妙的

ophunter的专栏 1086

poj——3740 Easy Finding

POJ - 3740 Easy Finding Time Limit: 1000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Submit Status Description Given a M× N matrix A. Aij ∈ {0, 1} (0

我们做的队 670

poj3740 Easy Finding 精确覆盖 舞蹈链/dfs

http://poj.org/problem?id=3740

473

POJ3740--Easy Finding(Dancing Links)

Description Given a M×N matrix A. Aij ∈ {0, 1} (0 ≤ i Input There are multiple cases ended by EOF. Test case up to 500.The first line of input is M, N (M ≤ 16, N ≤ 300). The next M lines e

SCUT_Pein 664

DLX算法

理解DLX算法之前首先了解精确覆盖问题和重复覆盖问题 精确覆盖问题 何为精确覆盖问题   在一个全集X中若干子集的集合为S,精确覆盖(Exactcover)是指,S的子集S*,满足X中的每一个元素在S*中恰好出现一次。 定义    满足以下条件的集合为一个精确覆盖:    S*中任意两个集合没有交集,即X中的元素在S*中出现最多一次    S*中集合的全集为X,即X中的元素...

dianzhenquan3519的博客 661

用Dancing Links求解精确覆盖问题

跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 例如:如下的矩阵 就包含了这样一个集合(第1、4、5行)   如何利用给定的矩阵求出相应的行的集合呢?我们采用回溯法   矩阵1:   先假定

QC的博客 1643

poj3074 Sudoku【DLX】【数独】【精确覆盖问题】

题目链接:http://poj.org/problem?id=3074 大佬题解链接:https://www.cnblogs.com/ylfdrib/archive/2010/10/06/1844559.html AC代码: #include<iostream> #include<cstdio> #include<cstdlib> #include<cma...

weixin_43499182的博客 326
上一篇: POJ输出状态的逻辑。
下一篇: 【POJ1084】Square Destroyer 重复覆盖问题 DLX(Dancing Links)
空灰冰魂
博客等级 码龄12年 83粉丝 392原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值