【算法】高斯消元-异或方程组

【题解】良心简中题意

首先开关顺序没有意义。

然后就是每个点选或不选使得最后得到全部灯开启。

也就是我们需要一种确定的方案,这种方案使每盏灯都是开启的。

异或中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 燈的更多相关文章

  1. BZOJ 1770: [Usaco2009 Nov]lights 燈( 高斯消元 )

    高斯消元解xor方程组...暴搜自由元+最优性剪枝 -------------------------------------------------------------------------- ...

  2. BZOJ 1770: [Usaco2009 Nov]lights 燈

    Description 一个图,对一个点进行操作会改变这个点及其相邻的点的状态,问全部变成黑色至少需要几次.数据保证有解. Sol Meet in middle. 我一开始写个高斯消元,发现有两个点过 ...

  3. 【高斯消元】BZOJ 1770: [Usaco2009 Nov]lights 燈

    Description 貝希和她的閨密們在她們的牛棚中玩遊戲.但是天不從人願,突然,牛棚的電源跳閘了,所有的燈都被關閉了.貝希是一個很膽小的女生,在伸手不見拇指的無盡的黑暗中,她感到驚恐,痛苦與絕望. ...

  4. BZOJ 1770: [Usaco2009 Nov]lights 燈 [高斯消元XOR 搜索]

    题意: 经典灯问题,求最少次数 本题数据不水,必须要暴搜自由元的取值啦 想了好久 然而我看到网上的程序都没有用记录now的做法,那样做遇到自由元应该可能会丢解吧...? 我的做法是把自由元保存下来,枚 ...

  5. bzoj 1770: [Usaco2009 Nov]lights 燈【高斯消元+dfs】

    参考:https://blog.csdn.net/qq_34564984/article/details/53843777 可能背了假的板子-- 对于每个灯建立方程:与它相邻的灯的开关次数的异或和为1 ...

  6. bzoj1770: [Usaco2009 Nov]lights 燈(折半搜索)

    1770: [Usaco2009 Nov]lights 燈 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1153  Solved: 564[Submi ...

  7. 【BZOJ 1770 】 [Usaco2009 Nov]lights 燈 dfs+异或方程组

    这道题明显是异或方程组,然而解不一定唯一他要的是众多解中解为1的数的最小值,这个时候我们就需要dfs了我们dfs的时候就是枚举其有不确定解的数上选0或1从而推知其他解,由于我们dfs的时候先0后1,虽 ...

  8. bzoj千题计划187:bzoj1770: [Usaco2009 Nov]lights 燈 (高斯消元解异或方程组+枚举自由元)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1770 a[i][j] 表示i对j有影响 高斯消元解异或方程组 然后dfs枚举自由元确定最优解 #in ...

  9. BZOJ1770 : [Usaco2009 Nov]lights 燈

    设$f[i]$表示$i$点按下开关后会影响到的点的集合,用二进制表示. 不妨设$n$为偶数,令$m=\frac{n}{2}$,对于前一半暴力$2^m$搜索所有方案,用map维护每种集合的最小代价. 对 ...

随机推荐

  1. OSI七层模型加协议

    OSI七层网络模型 TCP/IP四层概念模型 对应网络协议 应用层(Application) 应用层 HTTP.TFTP, FTP, NFS, WAIS.SMTP 表示层(Presentation) ...

  2. 今天买了个pro,开始ios开发

    今天买了个mac pro 开始ios开发啦,爽!

  3. Unity动态换装之Spine换装

    注:转载请注明转载,并附原链接 http://www.cnblogs.com/liaoguipeng/p/5867510.html 燕双飞情侣 一.动态换装原理 换装,无非就是对模型的网格,或者贴图进 ...

  4. python 基础篇 15 内置函数和匿名函数

    ------------------------>>>>>>>>>>>>>>>内置函数<<< ...

  5. Ubuntu 和 Windows 之间进行远程访问和文件互传

    1. 利用 Ubuntu 自带软件 Remmina 对另一台 Ubuntu 电脑进行远程访问(同一局域网下) 假设要用 A 电脑来控制 B 电脑,首先需要在 B 电脑上进行桌面共享设置 .   然后打 ...

  6. Drools 7.4.1.Final参考手册(十四)集成Spring

    集成Spring Drools 6.0重要变更 Drools Spring集成经历了与Drools 6.0的变化完全一致的改造. 以下是一些主要的变化: T*推荐的Drools Spring的前缀已经 ...

  7. QQ互联登陆的最简洁代码

    <?php/** * http://wiki.open.qq.com/wiki/ * Date: 14-6-18 * Time: 下午18:04 */class Model_Login_QqCo ...

  8. JVM高级内存优化面试

    Sun HotSpot VM,是JDK和Open JDK中自带的虚拟机,也是目前使用范围最广的Java虚拟机. JVM内存分布程序计数器:是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指 ...

  9. capacilitys docker中的权限设置 privileged

    capacilities是docker 中对docker权限设置的重要方面: http://blog.csdn.net/wangpengqi/article/details/9821227 上面这篇文 ...

  10. C#判断字符串是否为数字字符串

    在进行C#编程时候,有的时候我们需要判断一个字符串是否是数字字符串,我们可以通过以下两种方法来实现.[方法一]:使用 try{} catch{} 语句.      我们可以在try语句块中试图将str ...