高斯消元法求解异或方程组: cojs.tk 539.//BZOJ 1770 牛棚的灯
高斯消元求解异或方程组:
比较不错的一篇文章:http://blog.sina.com.cn/s/blog_51cea4040100g7hl.html
cojs.tk 539. 牛棚的灯
★★☆ 输入文件:lights.in
输出文件:lights.out
简单对比
时间限制:1 s 内存限制:128 MB
【问题描述】
贝希和她的闺密们在她们的牛棚中玩游戏。但是天不从人愿,突然,牛棚的电源跳闸了,所有的灯都被关闭了。贝希是一个很胆小的女生,在伸手不见拇指的无尽的黑暗中,她感到惊恐,痛苦与绝望。她希望您能够帮帮她,把所有的灯都给重新开起来!她才能继续快乐地跟她的闺密们继续玩游戏!
牛棚中一共有N(1 <= N <= 35)盏灯,编号为1到N。这些灯被置于一个非常复杂的网络之中。有M(1 <= M <= 595)条很神奇的无向边,每条边连接两盏灯。
每盏灯上面都带有一个开关。当按下某一盏灯的开关的时候,这盏灯本身,还有所有有边连向这盏灯的灯的状态都会被改变。状态改变指的是:当一盏灯是开着的时候,这盏灯被关掉;当一盏灯是关着的时候,这盏灯被打开。
问最少要按下多少个开关,才能把所有的灯都给重新打开。
数据保证至少有一种按开关的方案,使得所有的灯都被重新打开。
题目名称:lights
输入格式:
*第一行:两个空格隔开的整数:N和M。
*第二到第M+1行:每一行有两个由空格隔开的整数,表示两盏灯被一条无向边连接在一起。
没有一条边会出现两次。
样例输入(文件 lights.in):
5 6
1 2
1 3
4 2
3 4
2 5
5 3
输入细节:
一共有五盏灯。灯1、灯4和灯5都连接着灯2和灯3。
输出格式:
第一行:一个单独的整数,表示要把所有的灯都打开时,最少需要按下的开关的数目。
样例输出(文件 lights.out):
3
输出细节:
按下在灯1、灯4和灯5上面的开关。
hwzer的代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define inf 1000000000
#define ll long long
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m,tot;
int mn=inf;
int f[][],ans[];
void gauss()
{/*一共有n个方程,n个变量*/
for(int i=;i<=n;i++)
{
int j=i;/*第i行第i列是要向下消元的,如果该行是0,就找一个不是0的一行和他互换后,向下消元,如果j>n,说明所有行的第i列都是0,那就不用消元了*/
while(j<=n&&!f[j][i])j++;
if(j>n)continue;
if(i!=j)for(int k=;k<=n+;k++)swap(f[i][k],f[j][k]);/*互换*/
for(int j=i+;j<=n;j++)/*用第i行向下消元*/
if(i!=j&&f[j][i])/*消元时,只消这一项不是0的方程即可*/
for(int k=;k<=n+;k++)/*消这个方程的时候要把所有的量的都对应相消*/
f[j][k]^=f[i][k];
}
}
/*,因为,上面只是求出一组解,并不是最小解。
所以,我们需要求出所有解,然后输出最小的那个。
在求倒三角后,有一些m[i][i]==0,这时,我们对x[i]的取值就有两种,0或1。
本身,x[i]的取值对第i行的方程没有任何影响,但它的取值对其他方程有影响,
所以,这里需要枚举x[i]的取值。*/
void dfs(int now)
{/*tot表示按下灯的数目*/
if(tot>=mn)return;/*剪枝,取小操作,一旦大了就不用求了*/
if(!now)/*搜索的终点*/
{
mn=min(mn,tot);
return;
}
if(f[now][now])/*如果now不是自由变元*/
{/*这就是求出当前解ans[now]的过程,利用了性质t=a^b,那么t^b等于a,最后的 f[now][n+1],是由前面的ans[i](f[now][i]不等于0)异或得出的,可以异或回去,求出ans[now] */
int t=f[now][n+];
for(int i=now+;i<=n;i++)
if(f[now][i])t^=ans[i];
ans[now]=t;
if(t)tot++;/*如果当前的灯要按下,统计总数*/
dfs(now-);/*搜索上一盏灯*/
if(t)tot--;/*回溯的过程,为什么可以回溯呢,因为异或方程组会有多组解,即使当前的now灯不按下,求后面的now-1仍然可以有解,说不定还可以更优,所以要回溯*/
}
else /*如果now是自由变元,自由变元取到任何值,最终方程都会有解,就枚举x[now]是0还是1,进行搜索*/
{
ans[now]=;dfs(now-);
ans[now]=;tot++;dfs(now-);tot--;/*别忘记搜索中的回溯*/
}
}
int main()
{/*f[i][j]表示i--j有边相连,所以是1,其余的是0,在方程组中,*0后结果就没有影响了*/
freopen("lights.in","r",stdin);
freopen("lights.out","w",stdout);
n=read();m=read();
for(int i=;i<=n;i++)
f[i][i]=,f[i][n+]=;
for(int i=;i<=m;i++)
{
int x=read(),y=read();
f[x][y]=f[y][x]=;
}
gauss();dfs(n);/*从n开始搜索,是因为n的变元数目少*/
printf("%d\n",mn);
fclose(stdin);fclose(stdout);
return ;
}
我的代码:
#define N 40
#include<iostream>
using namespace std;
#include<cstdio>
#include<cstring>
int ans[N],f[N][N],x,y,n,m;
int minn=(<<)-,tot=;
int read()
{
int sum=,ff=;char s;
s=getchar();
while(s<''||s>'')
{
if(s=='-') ff=-;
s=getchar();
}
while(''<=s&&s<='')
{
sum=sum*+s-'';
s=getchar();
}
return sum*ff;
}
void gauss()
{
for(int i=;i<=n;++i)
{
int j=i;
while(j<=n&&!f[j][i]) j++;
if(j>n) continue;
if(i!=j)
{
for(int k=;k<=n+;++k)
{
swap(f[i][k],f[j][k]);
}
}
for(int j=i+;j<=n;++j)
if(f[j][i])
{
for(int k=;k<=n+;++k)
f[j][k]^=f[i][k];
}
}
}
void dfs(int now)
{
if(tot>=minn) return ;
if(!now)
{
minn=min(minn,tot);
return ;
}
if(f[now][now])
{
int t=f[now][n+];
for(int i=now+;i<=n;++i)
if(f[now][i]) t^=ans[i];
ans[now]=t;
if(t) tot++;
dfs(now-);
if(t) tot--;
}
else
{
ans[now]=;tot++;dfs(now-);
ans[now]=;tot--;dfs(now-);
}
}
int main()
{
// freopen("lights.in","r",stdin);
// freopen("lights.out","w",stdout);
n=read();m=read();
for(int i=;i<=n;++i)
f[i][i]=f[i][n+]=;
for(int i=;i<=m;++i)
{
x=read();
y=read();
f[x][y]=f[y][x]=;
}
gauss();
dfs(n);
printf("%d\n",minn);
// fclose(stdin);
// fclose(stdout);
return ;
}
高斯消元法求解异或方程组: cojs.tk 539.//BZOJ 1770 牛棚的灯的更多相关文章
- 【poj1830-开关问题】高斯消元求解异或方程组
第一道高斯消元题目~ 题目:有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关 ...
- 小游戏 Lights Out (关灯) 的求解 —— 异或方程组
Author : Evensgn Blog Link : http://www.cnblogs.com/JoeFan/ Article Link : http://www.cnblogs.com/J ...
- poj1222(高斯消元法解异或方程组+开关问题)
题目链接:https://vjudge.net/problem/POJ-1222 题意:给定一个5×6的01矩阵,改变一个点的状态时它上下左右包括它自己的状态都会翻转,因为翻转2次等价与没有翻转,那么 ...
- bzoj千题计划105:bzoj3503: [Cqoi2014]和谐矩阵(高斯消元法解异或方程组)
http://www.lydsy.com/JudgeOnline/problem.php?id=3503 b[i][j] 表示i对j是否有影响 高斯消元解异或方程组 bitset优化 #include ...
- fzu1704(高斯消元法解异或方程组+高精度输出)
题目链接:https://vjudge.net/problem/FZU-1704 题意:经典开关问题,求使得灯全0的方案数. 思路:题目保证至少存在一种方案,即方程组一定有解,那么套上高斯消元法的板子 ...
- 【poj1222-又一道开关问题】高斯消元求解异或方程组
题意:给出一个5*6的图,每个灯泡有一个初始状态,1表示亮,0表示灭.每对一个灯泡操作时,会影响周围的灯泡改变亮灭,问如何操作可以使得所有灯泡都关掉. 题解: 这题和上一题几乎完全一样..就是要输出解 ...
- BZOJ.1923.[SDOI2010]外星千足虫(高斯消元 异或方程组 bitset)
题目链接 m个方程,n个未知量,求解异或方程组. 复杂度比较高,需要借助bitset压位. 感觉自己以前写的(异或)高斯消元是假的..而且黄学长的写法都不需要回代. //1100kb 324ms #i ...
- UVa11542Squre——异或方程组&&高斯消元法
题意 给出 $n$ 个整数,从中选出1个或多个,使得选出的整数乘积是完全平方数.一共有多少种选法?($1 \leq n \leq 100$,$1 \leq a_i \leq 10^{15}$ 且不含大 ...
- 【HDU 5833】Zhu and 772002(异或方程组高斯消元)
300个最大质因数小于2000的数,选若干个它们的乘积为完全平方数有多少种方案. 合法方案的每个数的质因数的个数的奇偶值异或起来为0. 比如12=2^2*3,对应的奇偶值为01(2的个数是偶数为0,3 ...
随机推荐
- TypeScript在node项目中的实践
TypeScript在node项目中的实践 TypeScript可以理解为是JavaScript的一个超集,也就是说涵盖了所有JavaScript的功能,并在之上有着自己独特的语法.最近的一个新项目开 ...
- imperva系统升级遇见的错误(配置文件的导入导出)
今天心态有点炸了 今天去东兴证券做waf升级.浪费了两天才弄完.把客户都弄得有点急了.好歹原厂的工程师耐心的讲解这才弄完.感谢路哥.... 赶紧总结一下. 事情是这样的.东兴 证券的imperva是v ...
- 1-编程基础及Python环境部署
目录 1 编程基础 1.1 基本概念 1.2 语言分类 1.3 高级语言的发展 2 程序 3 python的语言介绍 4 Python的解释器 5 Python版本区别 6 Python安装 6.1 ...
- Git远程操作详解【转】
转自:http://www.ruanyifeng.com/blog/2014/06/git_remote.html 作者: 阮一峰 日期: 2014年6月12日 Git是目前最流行的版本管理系统,学会 ...
- 64_n3
nodejs-yamlish-0.0.5-9.fc26.noarch.rpm 11-Feb-2017 16:48 11966 nodejs-yargs-3.2.1-6.fc26.noarch.rpm ...
- Linux阵列 RAID详解 (转)
原文链接:http://molinux.blog.51cto.com/2536040/516008 一. RAID详解 二. mdadm工具介绍 三. 创建一个RAID的基本过程 四. ...
- beego学习笔记(4):开发文档阅读(1)
1.beego的设计是高度模块化的.每个模块,都可以单独使用.一共八大模块: cache;session;log;orm;context;httplibs;toolbox 2.beego的执行逻辑 3 ...
- MVC – 7.Razor 语法
7.1 Razor视图引擎语法 Razor通过理解标记的结构来实现代码和标记之间的顺畅切换. @核心转换字符,用来 标记-代码 的转换字符串. 语境A: @{ string rootName=&quo ...
- Jmeter----请求的reponse结果中的某个参数作为JDBC Request的查询条件
一.前言 数据库连接成功,若不会的查看:https://www.cnblogs.com/syw20170419/p/9832402.html 二.需求 将登录账号12608523691,接口的repo ...
- IE8/9的几个前端bug解决方案
最近做的东西需要兼容IE……啊真是令人忧伤…… 解决低版本IE的buggy inline-block 低版本的IE只对本身inline的元素能用inline-block,而本身为block的元素需要设 ...