BZOJ 1770: [Usaco2009 Nov]lights 燈 [高斯消元XOR 搜索]

Posted Candy?

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 1770: [Usaco2009 Nov]lights 燈 [高斯消元XOR 搜索]相关的知识,希望对你有一定的参考价值。

题意:

经典灯问题,求最少次数


 

本题数据不水,必须要暴搜自由元的取值啦

想了好久

然而我看到网上的程序都没有用记录now的做法,那样做遇到自由元应该可能会丢解吧...?

我的做法是把自由元保存下来,枚举的时候只枚举自由元

但这样没法最优性剪枝了

于是枚举的时候还是从n到1枚举,到i时如果i是主元这时候i的值已经可以算出来了,这样就可以最优性剪枝了

但注意主元i你不能用i这个方程,而要保存pivot[i]为i用了哪个方程

 

然后一个伪贪心策略是自由元先搜0

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bitset>
using namespace std;
const int N=40,INF=1e9;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<0||c>9){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
    return x*f;
}
int n,m,u,v;
bitset<N> a[N];
int fe[N],now;
void Gauss(){
    now=1;
    for(int i=1;i<=n;i++){
        int j=now;//printf("hi %d %d    %d\n",i,now,a[now][i]==1);
        while(j<=n&&!a[j][i]) j++;
        if(j==n+1) {fe[++fe[0]]=i;continue;}
        if(j!=now) swap(a[now],a[j]);
        for(int j=1;j<=n;j++)
            if(j!=now&&a[j][i]) a[j]^=a[now];
        now++;
    }
}    
int main(){
    freopen("in","r",stdin);
    n=read();m=read();
    for(int i=1;i<=m;i++) u=read(),v=read(),a[u][v]=a[v][u]=1;
    for(int i=1;i<=n;i++) a[i][n+1]=a[i][i]=1;
    Gauss();
    //for(int i=1;i<=n;i++) printf("a %d %d\n",i,a[i][n+1]==1);
    //for(int i=1;i<=fe[0];i++) printf("fe %d %d\n",i,fe[i]);
    int ans=0;
    for(int i=1;i<=now;i++) if(a[i][n+1]) ans++;
    printf("%d",ans);
}

 

以上是关于BZOJ 1770: [Usaco2009 Nov]lights 燈 [高斯消元XOR 搜索]的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 1770: [Usaco2009 Nov]lights 燈

bzoj 1770 [Usaco2009 Nov]lights 燈 meet in the middle

bzoj千题计划187:bzoj1770: [Usaco2009 Nov]lights 燈 (高斯消元解异或方程组+枚举自由元)

BZOJ 1770: [Usaco2009 Nov]lights 燈 [高斯消元XOR 搜索]

bzoj2017[Usaco2009 Nov]硬币游戏*

BZOJ 2017: [Usaco2009 Nov]硬币游戏(A Coin Game)