首页 > 代码库 > BZOJ1770: [Usaco2009 Nov]lights 燈

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\n",mn);110 111     return 0;112 113 }
View Code

 

 

 

BZOJ1770: [Usaco2009 Nov]lights 燈