【BZOJ】【1770】【Usaco2009 Nov】lights 灯
高斯消元解XOR方程组
一眼看上去是高斯消元解xor方程组……但是不会写……sad
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