• P2962 [USACO09NOV]灯Lights


    P2962 [USACO09NOV]灯Lights

    guass消元异或方程组

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 100
    #define sc(x) scanf("%lld",&x);
    #define int long long
    int A[maxn][maxn];
    int x[maxn];
    int ans=1000;
    int n,m;
    void guass()
    {
        for(int i=1; i<=n; i++)
        {
            int t=i;
            if(!A[t][t])
            {
                for(int j=i+1; j<=n; j++)
                {
                    if(A[j][i])
                    {
                        t=j;
                        break;
                    }
                }
                swap(A[i],A[t]);
            }
            for(int k=i+1; k<=n; k++)
            {
                if(A[k][i])
                {
                    for(int j=1; j<=n+1; j++)
                    {
                        A[k][j]^=A[i][j];///消元
                    }
                }
            }
    
        }
    }
    
    void dfs(int i,int t)
    {
        if(t>ans)return;
        if(i==0){
            ans=min(t,ans);
            return;
        }
        if(A[i][i]){
            x[i]=A[i][n+1];
            for(int j=i+1;j<=n;j++)
            if(A[i][j]){x[i]^=x[j];}
            if(x[i])dfs(i-1,t+1);
            else dfs(i-1,t);
        }else{
          x[i]=0;
          dfs(i-1,t);
          x[i]=1;
          dfs(i-1,t+1);
    
        }
    
    }
    signed main()
    {
        sc(n);sc(m);
        int x,y;
        while(m--){
            sc(x);sc(y);
            A[x][y]=A[y][x]=1;
        }
        for(int i=1;i<=n;i++)A[i][i]=A[i][n+1]=1;
        guass();
        dfs(n,0);
        cout<<ans<<'
    ';
    }

     折半枚举

    #include<bits/stdc++.h>
    #define LL long long
    #define RI register int
    using namespace std;
    const int INF = 0x7ffffff ;
    const int N = 40 ;
    
    inline int read()
    {
        int k = 0, f = 1 ;
        char c = getchar() ;
        for( ; !isdigit(c) ; c = getchar())
            if(c == '-') f = -1 ;
        for( ; isdigit(c) ; c = getchar())
            k = k*10 + c-'0' ;
        return k*f ;
    }
    int n, m, lv, ans = INF ;
    LL hh[N] ;
    LL tt ;
    LL p1[N], bin[N] ;
    bool flag ;
    map<LL,int>p ;  // 开不下2^35的数组,其实最多只有2^18个状态,所以用map是可以的
    
    void dfs(int now,LL res,int used)
    {
        if(now > lv)
        {
            if(res == tt)
            {
                ans = min(ans,used) ;
            }
            else
            {
                if(!flag)
                {
                    int t = p[res] ;
                    if(!t || used < t) p[res] = used ;
                }
                else
                {
                    if(p[tt^res]) ans = min(ans,p[tt^res]+used) ;
                }
            }
            return ;
        }
        dfs(now+1,res^p1[now],used+1) ;
        dfs(now+1,res,used) ; // 选与不选
    }
    
    int main()
    {
        n = read(), m = read() ;
        bin[0] = 1 ;
        for(int i=1; i<=n; i++) bin[i] = bin[i-1]<<1 ;
        tt = bin[n] - 1 ;
        memset(hh,0,sizeof(hh)) ;
        LL x, y ;
        for(int i=1; i<=m; i++)
        {
            x = read(), y = read() ;
            hh[x] ^= bin[y-1], hh[y] ^= bin[x-1] ;
        }
        for(int i=1; i<=n; i++) hh[i] ^= bin[i-1] ;
        lv = n>>1 ;
        for(int i=1; i<=lv; i++) p1[i] = hh[i] ;
        dfs(1,0,0) ;  // 搜索前一半
        for(int i=1; i<=n-lv; i++) p1[i] = hh[i+lv] ;
        lv = (n+1)>>1 ;
        flag = 1 ; // flag标记在搜索前半段还是后半段
        dfs(1,0,0) ;  // 搜索后一半
        printf("%d",ans) ;
        return 0 ;
    }
  • 相关阅读:
    属性与字段的区别
    修改LVDS支持1024*600分辨率
    Altium designer 10如何设置标题栏
    嵌入式C开发人员的最好的0x10道笔试题
    进程线程及堆栈关系的总结
    GDB调试
    c语言
    如何使用autotools生成Makefile
    ubuntu NFS
    Ubuntu安装配置TFTP服务
  • 原文地址:https://www.cnblogs.com/liulex/p/11417938.html
Copyright © 2020-2023  润新知