【BZOJ】1770 [Usaco2009 Nov]lights 燈
【算法】高斯消元-异或方程组
【题解】良心简中题意
首先开关顺序没有意义。
然后就是每个点选或不选使得最后得到全部灯开启。
也就是我们需要一种确定的方案,这种方案使每盏灯都是开启的。
异或中1可以完美实现取反。
故令xi表示第i盏灯的开关情况,然后对每盏灯的亮灭列方程,即
(1*x1)^(1*x2)^(0*x3)=1 该方程表示第1、2盏灯和该灯相邻(或就是该灯)
就这样n个方程对应n盏灯的亮灭。
题目不保证唯一解,所以可能存在自由元(即多解)。
之后就从n到1进行DFS,确定一个算一个。DFS中可以用最优性剪枝。
注意:虽然没有回代过程,a[x][n+1]的值仍然会改变得不一样,所以在dfs中每次要借用这个值必须用t来代之修改。不然动到原值,之后引用就会出错。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=,inf=0x3f3f3f3f;
int tot=,n,a[maxn][maxn],anss,ans,A[maxn],m; void gauss(){
for(int i=;i<=n;i++){
int r=;
for(int j=i;j<=n;j++)if(a[j][i]){r=j;break;}
if(r==)continue;
if(r!=i)for(int j=;j<=n+;j++)swap(a[i][j],a[r][j]);
for(int k=i+;k<=n;k++)if(a[k][i])
for(int j=i;j<=n+;j++)a[k][j]^=a[i][j];
}
} void dfs(int x){
if(anss>=ans)return;
if(x==){ans=anss;return;}
if(a[x][x]){
int t=a[x][n+];
for(int i=x+;i<=n;i++)t^=a[x][i]*A[i];
A[x]=t;
if(t)anss++;
dfs(x-);
if(t)anss--;
}
else{
A[x]=;dfs(x-);
A[x]=;anss++;dfs(x-);anss--;
}
}
int main(){
scanf("%d%d",&n,&m);
int u,v;
for(int i=;i<=m;i++){
scanf("%d%d",&u,&v);
a[u][v]=a[v][u]=;
}
for(int i=;i<=n;i++)a[i][i]=a[i][n+]=;
gauss();
ans=inf;anss=;
dfs(n);
printf("%d",ans);
return ;
}
另一种比较慢的是折半搜索(二分),技巧性比较强,空间换时间。
用二进制记录状态,枚举前半数点决策得到每个状态的最少按钮数。
枚举后半数点觉得得到的每个状态与契合状态(当前状态+契合状态=111111)的最少按钮数相加得到答案。
实质是通过记录状态,分段枚举,大大节约了时间。
【BZOJ】1770 [Usaco2009 Nov]lights 燈的更多相关文章
- BZOJ 1770: [Usaco2009 Nov]lights 燈( 高斯消元 )
高斯消元解xor方程组...暴搜自由元+最优性剪枝 -------------------------------------------------------------------------- ...
- BZOJ 1770: [Usaco2009 Nov]lights 燈
Description 一个图,对一个点进行操作会改变这个点及其相邻的点的状态,问全部变成黑色至少需要几次.数据保证有解. Sol Meet in middle. 我一开始写个高斯消元,发现有两个点过 ...
- 【高斯消元】BZOJ 1770: [Usaco2009 Nov]lights 燈
Description 貝希和她的閨密們在她們的牛棚中玩遊戲.但是天不從人願,突然,牛棚的電源跳閘了,所有的燈都被關閉了.貝希是一個很膽小的女生,在伸手不見拇指的無盡的黑暗中,她感到驚恐,痛苦與絕望. ...
- BZOJ 1770: [Usaco2009 Nov]lights 燈 [高斯消元XOR 搜索]
题意: 经典灯问题,求最少次数 本题数据不水,必须要暴搜自由元的取值啦 想了好久 然而我看到网上的程序都没有用记录now的做法,那样做遇到自由元应该可能会丢解吧...? 我的做法是把自由元保存下来,枚 ...
- bzoj 1770: [Usaco2009 Nov]lights 燈【高斯消元+dfs】
参考:https://blog.csdn.net/qq_34564984/article/details/53843777 可能背了假的板子-- 对于每个灯建立方程:与它相邻的灯的开关次数的异或和为1 ...
- bzoj1770: [Usaco2009 Nov]lights 燈(折半搜索)
1770: [Usaco2009 Nov]lights 燈 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1153 Solved: 564[Submi ...
- 【BZOJ 1770 】 [Usaco2009 Nov]lights 燈 dfs+异或方程组
这道题明显是异或方程组,然而解不一定唯一他要的是众多解中解为1的数的最小值,这个时候我们就需要dfs了我们dfs的时候就是枚举其有不确定解的数上选0或1从而推知其他解,由于我们dfs的时候先0后1,虽 ...
- bzoj千题计划187:bzoj1770: [Usaco2009 Nov]lights 燈 (高斯消元解异或方程组+枚举自由元)
http://www.lydsy.com/JudgeOnline/problem.php?id=1770 a[i][j] 表示i对j有影响 高斯消元解异或方程组 然后dfs枚举自由元确定最优解 #in ...
- BZOJ1770 : [Usaco2009 Nov]lights 燈
设$f[i]$表示$i$点按下开关后会影响到的点的集合,用二进制表示. 不妨设$n$为偶数,令$m=\frac{n}{2}$,对于前一半暴力$2^m$搜索所有方案,用map维护每种集合的最小代价. 对 ...
随机推荐
- 环境变量 - Maven
Linux 1. 备份并编辑配置文件 # cp /etc/profile /etc/profile.bak # vi /etc/profile 2. 设置Maven环境变量 export MAVEN_ ...
- linux基础重要命令小节
此为L005&&L006课程内容的一个总结. 命令: 基本形式 命令 [参数] [路径或文件] 例:ls -ld /data pwd 目前所在目录 [root@moban /]# pw ...
- Python初步
准备在工作之余看看Python的东西 收录一些资料 Python初学者(零基础学习Python.Python入门)常见问题:书籍推荐.资料.社区 http://blog.csdn.net/xiaowa ...
- 近期准备发布我的asp.net框架
此框架为超轻量级架构,适合做中小型的b/s项目
- 第二十四篇configparser(**)
configparser模块 config:配置,parser:解析.字面意思理解configparser模块就是配置文件的解析模块. 来看一个好多软件的常见文档格式如下: [DEFAULT] # 标 ...
- Visual Studio 2014安装包
点击下载
- LeetCode 33——搜索旋转排序数组
1. 题目 2. 解答 2.1. 方法一 直接进行二分查找,在判断查找方向的时候详细分类. 当 nums[mid] < target 时, 若 nums[left] <= nums[mid ...
- 从零开始搭建一个react项目
Nav logo 120 发现 关注 消息 4 搜索 从零开始搭建一个react项目 96 瘦人假噜噜 2017.04.23 23:29* 字数 6330 阅读 32892评论 31喜欢 36 项目地 ...
- CubieTruck使用笔记--SD卡中使用lubuntu
http://docs.cubieboard.org/tutorials/ct1/installation/install_lubuntu_desktop_server_to_sd_card 按照上面 ...
- Pandoc中的Markdown语法
概述 Pandoc中支持扩展修订版本的Markdown语法 使用pandoc中支持的Markdown语法用 -f markdown 使用标准Markdown语法用 -f markdown_strict ...