zoukankan      html  css  js  c++  java
  • BZOJ1770: [Usaco2009 Nov]lights 燈

    Description

    貝 希和她的閨密們在她們的牛棚中玩遊戲。但是天不從人願,突然,牛棚的電源跳閘了,所有的燈都被關閉了。貝希是一個很膽小的女生,在伸手不見拇指的無盡的黑 暗中,她感到驚恐,痛苦與絕望。她希望您能夠幫幫她,把所有的燈都給重新開起來!她才能繼續快樂地跟她的閨密們繼續玩遊戲! 牛棚中一共有N(1 <= N <= 35)盞燈,編號為1到N。這些燈被置於一個非常複雜的網絡之中。有M(1 <= M <= 595)條很神奇的無向邊,每條邊連接兩盞燈。 每盞燈上面都帶有一個開關。當按下某一盞燈的開關的時候,這盞燈本身,還有所有有邊連向這盞燈的燈的狀態都會被改變。狀態改變指的是:當一盞燈是開著的時 候,這盞燈被關掉;當一盞燈是關著的時候,這盞燈被打開。 問最少要按下多少個開關,才能把所有的燈都給重新打開。 數據保證至少有一種按開關的方案,使得所有的燈都被重新打開。

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1770

    题解:

    看了题之后发现好像是异或的高斯消元,然后发现我好像不会。。。

    膜拜了hzwer的代码。。。

    最后居然还要爆搜。果断抄代码。

    一些注释写在代码里。。。

    需要注意的是 f[i][i]=0 表示 i 是自由变量

    代码:

      1 #include<cstdio>
      2 
      3 #include<cstdlib>
      4 
      5 #include<cmath>
      6 
      7 #include<cstring>
      8 
      9 #include<algorithm>
     10 
     11 #include<iostream>
     12 
     13 #include<vector>
     14 
     15 #include<map>
     16 
     17 #include<set>
     18 
     19 #include<queue>
     20 
     21 #include<string>
     22 
     23 #define inf 1000000000
     24 
     25 #define maxn 500+100
     26 
     27 #define maxm 500+100
     28 
     29 #define eps 1e-10
     30 
     31 #define ll long long
     32 
     33 #define pa pair<int,int>
     34 
     35 #define for0(i,n) for(int i=0;i<=(n);i++)
     36 
     37 #define for1(i,n) for(int i=1;i<=(n);i++)
     38 
     39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
     40 
     41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
     42 
     43 #define mod 1000000007
     44 
     45 using namespace std;
     46 
     47 inline int read()
     48 
     49 {
     50 
     51     int x=0,f=1;char ch=getchar();
     52 
     53     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     54 
     55     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
     56 
     57     return x*f;
     58 
     59 }
     60 int n,m,tot;
     61 int mn=inf;
     62 int f[45][45],ans[45];
     63 void gauss()
     64 {
     65     for1(i,n)
     66     {
     67         int j=i;
     68         while(j<=n&&!f[j][i])j++;
     69         if(j>n)continue;
     70         if(j!=i)for1(k,n+1)swap(f[i][k],f[j][k]);
     71         for2(j,i+1,n)
     72          if(f[j][i])
     73              for2(k,i,n+1)
     74               f[j][k]^=f[i][k];
     75      }
     76 }
     77 inline void dfs(int x)
     78 {
     79     if(tot>=mn)return;//最优性剪枝
     80     if(!x){mn=min(mn,tot);return;}//终点
     81     if(f[x][x])//已被限制是否需要按下
     82     {
     83         int t=f[x][n+1];
     84         for2(i,x+1,n)if(f[x][i])t^=ans[i];
     85         ans[x]=t;
     86         if(t)tot++;
     87         dfs(x-1);//继续深搜
     88         if(t)tot--;//还原,回溯
     89     }
     90     else//自由变量
     91     {
     92         ans[x]=0;dfs(x-1);//假设不按该灯开关
     93         ans[x]=1;tot++;dfs(x-1);tot--;//假设按该灯开关
     94     }
     95 }
     96 
     97 int main()
     98 
     99 {
    100 
    101     freopen("input.txt","r",stdin);
    102 
    103     freopen("output.txt","w",stdout);
    104 
    105     n=read();m=read();
    106     for1(i,n)f[i][i]=1,f[i][n+1]=1;
    107     for1(i,m){int x=read(),y=read();f[x][y]=f[y][x]=1;}
    108     gauss();dfs(n);
    109     printf("%d
    ",mn);
    110 
    111     return 0;
    112 
    113 }
    View Code
  • 相关阅读:
    Oracle使用笔记
    跳转至锚点
    项目中使用到的AOP
    短信验证码接口使用
    阿里人脸识别接口
    java实现网页截图
    java后台接收微信服务号/订阅号消息
    java 实现redis缓存
    redis 常用命令
    被骗了,自己还不知道
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4059245.html
Copyright © 2011-2022 走看看