码迷,mamicode.com
首页 > 其他好文 > 详细

POJ.1830.开关问题(高斯消元)

时间:2018-02-13 10:31:37      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:def   需要   git   etc   blog   swap   ==   down   algo   

题目链接
显然我们需要使每个i满足\(( ∑_{j} X[j]*A[i][j] ) % 2 = B[i]\)
求这个方程自由元Xi的个数ans,那么方案数便是\(2^{ans}\)
%2可以用^代替,不难看出 B[i]=st[i]^ed[i]
如果X[j]=1,假设j会影响i,那么X[j]*A[i][j]这一项应为1,所以A[i][j]应=1 输入别反!
注意A[i][i]=1
将系数矩阵化为上三角形式后,剩下的系数全为0的行数就是自由元的个数;
如果某一行系数全为零,增广矩阵最后一列对应行的值不为0,则无解
//硬是被输入反了坑了半天。。

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
const int N=31;

inline int read()
{
    int now=0,f=1;register char c=gc();
    for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now*f;
}
struct Gauss
{
    int n;
    bool A[N][N];
    void Init()
    {
        memset(A,0,sizeof A);
        n=read();
        for(int i=0; i<n; ++i) A[i][n]=read();
        for(int i=0; i<n; ++i) A[i][n]^=read();
        for(int i=0; i<n; ++i) A[i][i]=1;
        int a,b;
        while(a=read(),b=read(),a&&b) A[b-1][a-1]=1;//a,b别反!
    }
    void Solve()
    {
        int r=0,c=0;
        while(r<n && c<n)
        {
            int mxrow=r;
            for(int i=r+1; i<n; ++i)
                if(A[i][c]>A[mxrow][c]) mxrow=i;
            if(!A[mxrow][c]) {++c; continue;}
            if(mxrow!=r) std::swap(A[r],A[mxrow]);
            for(int i=r+1; i<n; ++i)
                if(A[i][c])
                    for(int j=c; j<=n; ++j)
                        A[i][j]^=A[r][j];
            ++r, ++c;
        }//从r往后的行的矩阵元素都为0 
        for(int i=r; i<n; ++i)//某一行系数全为0但最后一列不为0 
            if(A[i][n]) {puts("Oh,it's impossible~!!"); return;}
        printf("%d\n",1<<(n-r));
    }
}g;

int main()
{
    int t=read();
    while(t--) g.Init(), g.Solve();
    return 0;
}

POJ.1830.开关问题(高斯消元)

标签:def   需要   git   etc   blog   swap   ==   down   algo   

原文地址:https://www.cnblogs.com/SovietPower/p/8445969.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!