高斯消元求解异或方程组:

比较不错的一篇文章: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的代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cstdlib>
  5. #include<algorithm>
  6. #include<cmath>
  7. #define inf 1000000000
  8. #define ll long long
  9. using namespace std;
  10. inline int read()
  11. {
  12. int x=,f=;char ch=getchar();
  13. while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
  14. while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
  15. return x*f;
  16. }
  17. int n,m,tot;
  18. int mn=inf;
  19. int f[][],ans[];
  20. void gauss()
  21. {/*一共有n个方程,n个变量*/
  22. for(int i=;i<=n;i++)
  23. {
  24. int j=i;/*第i行第i列是要向下消元的,如果该行是0,就找一个不是0的一行和他互换后,向下消元,如果j>n,说明所有行的第i列都是0,那就不用消元了*/
  25. while(j<=n&&!f[j][i])j++;
  26. if(j>n)continue;
  27. if(i!=j)for(int k=;k<=n+;k++)swap(f[i][k],f[j][k]);/*互换*/
  28. for(int j=i+;j<=n;j++)/*用第i行向下消元*/
  29. if(i!=j&&f[j][i])/*消元时,只消这一项不是0的方程即可*/
  30. for(int k=;k<=n+;k++)/*消这个方程的时候要把所有的量的都对应相消*/
  31. f[j][k]^=f[i][k];
  32. }
  33. }
  34. /*,因为,上面只是求出一组解,并不是最小解。
  35. 所以,我们需要求出所有解,然后输出最小的那个。
  36. 在求倒三角后,有一些m[i][i]==0,这时,我们对x[i]的取值就有两种,0或1。
  37. 本身,x[i]的取值对第i行的方程没有任何影响,但它的取值对其他方程有影响,
  38. 所以,这里需要枚举x[i]的取值。*/
  39. void dfs(int now)
  40. {/*tot表示按下灯的数目*/
  41. if(tot>=mn)return;/*剪枝,取小操作,一旦大了就不用求了*/
  42. if(!now)/*搜索的终点*/
  43. {
  44. mn=min(mn,tot);
  45. return;
  46. }
  47. if(f[now][now])/*如果now不是自由变元*/
  48. {/*这就是求出当前解ans[now]的过程,利用了性质t=a^b,那么t^b等于a,最后的 f[now][n+1],是由前面的ans[i](f[now][i]不等于0)异或得出的,可以异或回去,求出ans[now] */
  49. int t=f[now][n+];
  50. for(int i=now+;i<=n;i++)
  51. if(f[now][i])t^=ans[i];
  52. ans[now]=t;
  53. if(t)tot++;/*如果当前的灯要按下,统计总数*/
  54. dfs(now-);/*搜索上一盏灯*/
  55. if(t)tot--;/*回溯的过程,为什么可以回溯呢,因为异或方程组会有多组解,即使当前的now灯不按下,求后面的now-1仍然可以有解,说不定还可以更优,所以要回溯*/
  56. }
  57. else /*如果now是自由变元,自由变元取到任何值,最终方程都会有解,就枚举x[now]是0还是1,进行搜索*/
  58. {
  59. ans[now]=;dfs(now-);
  60. ans[now]=;tot++;dfs(now-);tot--;/*别忘记搜索中的回溯*/
  61. }
  62. }
  63. int main()
  64. {/*f[i][j]表示i--j有边相连,所以是1,其余的是0,在方程组中,*0后结果就没有影响了*/
  65. freopen("lights.in","r",stdin);
  66. freopen("lights.out","w",stdout);
  67. n=read();m=read();
  68. for(int i=;i<=n;i++)
  69. f[i][i]=,f[i][n+]=;
  70. for(int i=;i<=m;i++)
  71. {
  72. int x=read(),y=read();
  73. f[x][y]=f[y][x]=;
  74. }
  75. gauss();dfs(n);/*从n开始搜索,是因为n的变元数目少*/
  76. printf("%d\n",mn);
  77. fclose(stdin);fclose(stdout);
  78. return ;
  79. }

我的代码:

  1. #define N 40
  2. #include<iostream>
  3. using namespace std;
  4. #include<cstdio>
  5. #include<cstring>
  6. int ans[N],f[N][N],x,y,n,m;
  7. int minn=(<<)-,tot=;
  8. int read()
  9. {
  10. int sum=,ff=;char s;
  11. s=getchar();
  12. while(s<''||s>'')
  13. {
  14. if(s=='-') ff=-;
  15. s=getchar();
  16. }
  17. while(''<=s&&s<='')
  18. {
  19. sum=sum*+s-'';
  20. s=getchar();
  21. }
  22. return sum*ff;
  23. }
  24. void gauss()
  25. {
  26. for(int i=;i<=n;++i)
  27. {
  28. int j=i;
  29. while(j<=n&&!f[j][i]) j++;
  30. if(j>n) continue;
  31. if(i!=j)
  32. {
  33. for(int k=;k<=n+;++k)
  34. {
  35. swap(f[i][k],f[j][k]);
  36. }
  37. }
  38. for(int j=i+;j<=n;++j)
  39. if(f[j][i])
  40. {
  41. for(int k=;k<=n+;++k)
  42. f[j][k]^=f[i][k];
  43. }
  44. }
  45. }
  46. void dfs(int now)
  47. {
  48. if(tot>=minn) return ;
  49. if(!now)
  50. {
  51. minn=min(minn,tot);
  52. return ;
  53. }
  54. if(f[now][now])
  55. {
  56. int t=f[now][n+];
  57. for(int i=now+;i<=n;++i)
  58. if(f[now][i]) t^=ans[i];
  59. ans[now]=t;
  60. if(t) tot++;
  61. dfs(now-);
  62. if(t) tot--;
  63. }
  64. else
  65. {
  66. ans[now]=;tot++;dfs(now-);
  67. ans[now]=;tot--;dfs(now-);
  68. }
  69. }
  70. int main()
  71. {
  72. // freopen("lights.in","r",stdin);
  73. // freopen("lights.out","w",stdout);
  74. n=read();m=read();
  75. for(int i=;i<=n;++i)
  76. f[i][i]=f[i][n+]=;
  77. for(int i=;i<=m;++i)
  78. {
  79. x=read();
  80. y=read();
  81. f[x][y]=f[y][x]=;
  82. }
  83. gauss();
  84. dfs(n);
  85. printf("%d\n",minn);
  86. // fclose(stdin);
  87. // fclose(stdout);
  88. return ;
  89. }

高斯消元法求解异或方程组: cojs.tk 539.//BZOJ 1770 牛棚的灯的更多相关文章

  1. 【poj1830-开关问题】高斯消元求解异或方程组

    第一道高斯消元题目~ 题目:有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关 ...

  2. 小游戏 Lights Out (关灯) 的求解 —— 异或方程组

    Author : Evensgn  Blog Link : http://www.cnblogs.com/JoeFan/ Article Link : http://www.cnblogs.com/J ...

  3. poj1222(高斯消元法解异或方程组+开关问题)

    题目链接:https://vjudge.net/problem/POJ-1222 题意:给定一个5×6的01矩阵,改变一个点的状态时它上下左右包括它自己的状态都会翻转,因为翻转2次等价与没有翻转,那么 ...

  4. bzoj千题计划105:bzoj3503: [Cqoi2014]和谐矩阵(高斯消元法解异或方程组)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3503 b[i][j] 表示i对j是否有影响 高斯消元解异或方程组 bitset优化 #include ...

  5. fzu1704(高斯消元法解异或方程组+高精度输出)

    题目链接:https://vjudge.net/problem/FZU-1704 题意:经典开关问题,求使得灯全0的方案数. 思路:题目保证至少存在一种方案,即方程组一定有解,那么套上高斯消元法的板子 ...

  6. 【poj1222-又一道开关问题】高斯消元求解异或方程组

    题意:给出一个5*6的图,每个灯泡有一个初始状态,1表示亮,0表示灭.每对一个灯泡操作时,会影响周围的灯泡改变亮灭,问如何操作可以使得所有灯泡都关掉. 题解: 这题和上一题几乎完全一样..就是要输出解 ...

  7. BZOJ.1923.[SDOI2010]外星千足虫(高斯消元 异或方程组 bitset)

    题目链接 m个方程,n个未知量,求解异或方程组. 复杂度比较高,需要借助bitset压位. 感觉自己以前写的(异或)高斯消元是假的..而且黄学长的写法都不需要回代. //1100kb 324ms #i ...

  8. UVa11542Squre——异或方程组&&高斯消元法

    题意 给出 $n$ 个整数,从中选出1个或多个,使得选出的整数乘积是完全平方数.一共有多少种选法?($1 \leq n \leq 100$,$1 \leq a_i \leq 10^{15}$ 且不含大 ...

  9. 【HDU 5833】Zhu and 772002(异或方程组高斯消元)

    300个最大质因数小于2000的数,选若干个它们的乘积为完全平方数有多少种方案. 合法方案的每个数的质因数的个数的奇偶值异或起来为0. 比如12=2^2*3,对应的奇偶值为01(2的个数是偶数为0,3 ...

随机推荐

  1. Django之jsonp跨域请求原理

    在进行网站开发的过程中经常会用到第三方的数据,但是由于同源策略的限制导致ajax不能发送请求,因此也无法获得数据.解决ajax的跨域问题有两种方法: 一.jsonp 二.XMLHttpRequest2 ...

  2. WordPress浏览数插件的安装使用

    插件安装很容易,但是和大多插件都一样,安装后需要调用代码才能显示,我安装后,也调用了.但是就是不显示,后来才发现,我从其他地方复制过来的代码,函数是中文的单引号,这样致使函数失效,注意代码中参数的引号 ...

  3. 多线程中的超时, 如Socket超时

    ; ,,, ->$port { print "-->$port\r"; #say "\r"; await Promise.anyof( Promis ...

  4. 千字短文解决工程师们关于SPI的迷糊!

    串行外设接口 (SPI) 总线是一个工作在全双工模式下的同步串行数据链路.它可用于在单个主控制器和一个或多个从设备之间交换数据.其简单的实施方案只使用四条支持数据与控制的信号线(图 1): 图1:基本 ...

  5. 64_t3

    texlive-dice-svn28501.0-33.fc26.2.noarch.rpm 24-May-2017 15:52 36490 texlive-dichokey-doc-svn17192.0 ...

  6. 【bzoj4293】【PA2015】Siano

    如题,首先可以考虑相对大小是不变的. 那么先sort,之后每次在线段树上二分即可. #include<bits/stdc++.h> typedef long long ll; using ...

  7. 「caffe编译bug」python/caffe/_caffe.cpp:10:31: fatal error: numpy/arrayobject.h: No such file or directory

    在Makefile.config找到PYTHON_INCLUDE,发现有点不同: PYTHON_INCLUDE := /usr/include/python2.7 \         /usr/lib ...

  8. rcnn ->fast rcnn->faster rcnn物体检测论文

    faster rcnn中的rpn网络: 特征可以看做一个尺度51*39的256通道图像,对于该图像的每一个位置,考虑9个可能的候选窗口:三种面积{1282,2562,5122}×三种比例{1:1,1: ...

  9. Weblogic常用监控指标以及监控工具小结

    https://blog.csdn.net/hualusiyu/article/details/39583549

  10. git客户端基本操作

    首先下载git 一路next安装好了之后,打开任意盘符,右键打开git bash here 首先:初始首次的用户名和邮箱,之后就不用了. git config --global user.name & ...