【BZOJ】【1770】【Usaco2009 Nov】lights 灯

高斯消元解XOR方程组

  一眼看上去是高斯消元解xor方程组……但是不会写……sad

  去膜拜了HzwerZYF

  Hzwer啥也没说,还是zyf靠谱……

  当多解的时候就需要爆搜枚举自由元的情况,找最优解……

o(︶︿︶)o 唉我还是太弱了

 

zyf的解释:

 1 inline void dfs(int x)
 2 {
 3     if(tot>=mn)return;//最优性剪枝
 4     if(!x){mn=min(mn,tot);return;}//终点
 5     if(f[x][x])//已被限制是否需要按下
 6     {
 7         int t=f[x][n+1];
 8         for2(i,x+1,n)if(f[x][i])t^=ans[i];
 9         ans[x]=t;
10         if(t)tot++;
11         dfs(x-1);//继续深搜
12         if(t)tot--;//还原,回溯
13     }
14     else//自由变量
15     {
16         ans[x]=0;dfs(x-1);//假设不按该灯开关
17         ans[x]=1;tot++;dfs(x-1);tot--;//假设按该灯开关
18     }
19 }

 

 1 /**************************************************************
 2     Problem: 1770
 3     User: Tunix
 4     Language: C++
 5     Result: Accepted
 6     Time:4 ms
 7     Memory:1284 kb
 8 ****************************************************************/
 9  
10 //BZOJ 1770
11 #include<cstdio>
12 #include<cstring>
13 #include<cstdlib>
14 #include<iostream>
15 #include<algorithm>
16 #define rep(i,n) for(int i=0;i<n;++i)
17 #define F(i,j,n) for(int i=j;i<=n;++i)
18 #define D(i,j,n) for(int i=j;i>=n;--i)
19 using namespace std;
20 const int N=50;
21 typedef long long LL;
22 int n,m,f[N][N],_min=1e7,ans[N],tot;
23  
24 void gauss(){
25     F(i,1,n){
26         int j=i;
27         while(j<=n && !f[j][i]) j++;
28         if(j>n) continue;
29         if(i!=j) F(k,1,n+1) swap(f[i][k],f[j][k]);
30         F(j,1,n) if(i!=j && f[j][i])
31             F(k,1,n+1) f[j][k]^=f[i][k];
32     }
33 }
34 void dfs(int x){
35     if(tot>=_min) return;
36     if(!x){
37         _min=min(_min,tot);
38         return;
39     }
40     if(f[x][x]){
41         int t=f[x][n+1];
42         F(i,x+1,n)
43             if(f[x][i]) t^=ans[i];
44         ans[x]=t;
45         if(t) tot++;
46         dfs(x-1);
47         if(t) tot--;
48     }
49     else{
50         ans[x]=0; dfs(x-1);
51         ans[x]=1; tot++; dfs(x-1); tot--;
52     }
53 }
54 int main(){
55     scanf("%d%d",&n,&m);
56     F(i,1,n) f[i][i]=f[i][n+1]=1;
57     int x,y;
58     F(i,1,m){
59         scanf("%d%d",&x,&y);
60         f[x][y]=f[y][x]=1;
61     }
62     gauss();
63     dfs(n);
64     printf("%d\n",_min);
65     return 0;
66 }
67 
View Code

 

posted @ 2015-01-30 21:33  Tunix  阅读(262)  评论(0编辑  收藏  举报