• 【dfs】【高斯消元】【异或方程组】bzoj1770 [Usaco2009 Nov]lights 燈 / bzoj2466 [中山市选2009]树


    经典的开关灯问题。

    高斯消元后矩阵对角线B[i][i]若是0,则第i个未知数是自由元(S个),它们可以任意取值,而让非自由元顺应它们,得到2S组解。

    枚举自由元取0/1,最终得到最优解。

    不知为何正着搜不行。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 36
    int n,m;
    int ans=2147483647;
    bool B[N][N+1],x[N],path[N];
    void Madoka()
    {
        for(int i=1;i<=n;++i)
          {
            int j=i;
            for(;j<=n;++j) if(B[j][i]) break;
            if(j!=n+1)
              {
                swap(B[i],B[j]);
                for(j=1;j<=n;++j)
                  if(i!=j&&B[j][i])
                    for(int k=1;k<=n+1;++k)
                      B[j][k]^=B[i][k];
              }
          }
    }
    void dfs(int cur,int now)
    {
        if(now>=ans) return;
        if(!cur) {ans=now; return;}
        if(B[cur][cur])
          {
            bool t=B[cur][n+1];
            for(int i=cur+1;i<=n;++i)
              if(B[cur][i]) t^=path[i];
            path[cur]=t;
            dfs(cur-1,now+t);
          }
        else
          {
            path[cur]=0; dfs(cur-1,now);
            path[cur]=1; dfs(cur-1,now+1);
          }
    }
    int main()
    {
        int x,y;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i) B[i][n+1]=1,B[i][i]=1;
        for(int i=1;i<=m;++i)
          {
            scanf("%d%d",&x,&y);
            B[x][y]=B[y][x]=1;
          }
        Madoka();
        dfs(n,0);
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    洛谷P1033 自由落体 题解
    尴尬
    UVA11988 【Broken Keyboard (a.k.a. Beiju Text)】:题解
    UVA101 The Blocks Problem 题解
    TCP的粘包和拆包问题及解决办法(C#)
    MIPS学习笔记(一)
    MySQL基础(一)
    博客园的标签怎么变了两下???
    nextInt()和nextLine()连用报错
    C++代码雨
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4367878.html
Copyright © 2020-2023  润新知