zoukankan      html  css  js  c++  java
  • 【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;
    }
  • 相关阅读:
    Epoll技术深入学习
    nginx
    epoll案例
    Linux网络编程初步
    链表快速排序(已通过ACM在线评测)
    C++内存管理
    c++11并发语法初步
    数据库与SQL优化笔记(一)
    C++面向对象模型(虚表与虚表指针)
    c++的一些杂项
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4367878.html
Copyright © 2011-2022 走看看