poj 1830 开关问题(高斯消元)

来源:互联网 发布:java html转义 编辑:程序博客网 时间:2024/06/08 03:00

线代真是白学了这里写图片描述
题解:http://blog.csdn.net/u011418307/article/details/52328759
只要构造出来方程,剩下就很简单了。。

#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;//对2取模的01方程组const int MAXN = 40;int g[MAXN][MAXN];int S[MAXN],E[MAXN],n;int Gauss(){    int maxR,col,k;    for(k = 0, col = 0 ; k < n && col < n ; k++, col++)    {        maxR = k;        for(int i = k+1; i < n; i++)        {            if(abs(g[i][col]) > abs(g[maxR][col]))                maxR = i;        }        if(g[maxR][col] == 0)        {            k--;            continue;        }        if(maxR != k)        {            for(int j = col; j < n+1; j++)                swap(g[k][j],g[maxR][j]);        }        for(int i = k+1; i < n; i++)        {            if(g[i][col] != 0)            {                for(int j = col; j < n+1; j++)                    g[i][j] ^= g[k][j];            }        }    }    for(int i = k; i < n; i++)        if(g[i][col] != 0)            return -1;   return n-k;}int main(){    int T;    scanf("%d",&T);    while(T--)    {        memset(g,0,sizeof(g));        scanf("%d",&n);        for(int i = 0; i < n; i++)        {            g[i][i] = 1;            scanf("%d",&S[i]);        }        for(int i = 0; i < n; i++)        {            scanf("%d",&E[i]);            g[i][n] = (S[i]^E[i]);        }        int u,v;        while(scanf("%d%d",&u,&v) && u+v)            g[v-1][u-1] = 1;        int t = Gauss();        if(t == -1) printf("Oh,it's impossible~!!\n");        else printf("%d\n",(1<<t));    }    return 0;}