• 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,pivot[N];
    void Gauss(){
        now=1;
        for(int i=1;i<=n;i++){
            int j=now;//printf("hi %d %d    %d
    ",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];
            pivot[i]=now;//printf("pivot %d
    ",i);
            now++;
        }
    }   
    int val[N],tot,ans=INF;
    void pri(){
        puts("free");
        for(int i=1;i<=fe[0];i++) printf("fe %d %d %d
    ",i,fe[i],val[i]);
        puts("end");
    }
    int fir=1;
    void dfs(int d){
        //printf("dfs %d %d
    ",d,tot);
        if(tot>=ans) return;
        if(d==0) ans=min(ans,tot);//if(fir==1) printf("tot %d
    ",tot),pri(),fir=0;}
        else if(pivot[d]){//printf("d %d
    ",d);
            int i=pivot[d];
            int _=a[i][n+1];
            for(int j=1;j<=fe[0];j++)
                if(a[i][fe[j]]) _^=val[fe[j]];
            tot+=_;
            dfs(d-1);
            tot-=_;
        }else{
            val[d]=0;
            dfs(d-1);
            val[d]=1; tot++;
            dfs(d-1);
            tot--;
        }
    }
    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
    ",i,a[i][n+1]==1);
        //for(int i=1;i<=fe[0];i++) printf("fe %d %d
    ",i,fe[i]);
        dfs(n);
        printf("%d",ans);
    }
  • 相关阅读:
    Spring事务(三)事务增强器
    Spring事务(二)事务自定义标签
    Spring事务(一)JDBC方式下的事务使用示例
    Spring整合MyBatis(五)MapperScannerConfigurer
    Spring整合MyBatis(四)MapperFactoryBean 的创建
    BOS物流管理系统-第五天
    BOS物流管理系统-第一天
    SSM
    【剑指offer】翻转单词顺序,C++实现
    【特征选择】嵌入式特征选择法
  • 原文地址:https://www.cnblogs.com/candy99/p/6413227.html
Copyright © 2020-2023  润新知