hdu 3364 Lanterns 高斯消元,模板题
来源:互联网 发布:人人玩棋牌源码 编辑:程序博客网 时间:2024/05/16 05:03
#include <cstdio>#include <cstring>#include <cmath>#include <map>#include <queue>#include <stack>#include <iostream>#include <algorithm>using namespace std;const int maxn=55;struct matrix{ int f[maxn][maxn];}e,g;int find(matrix a,int m,int n)//高斯消元{ int i=1,j=1,k,r,u; while(i<=m&&j<=n)//处理第i个方程,第j个变量 { r=i; for(k=i;k<=m;k++) if(a.f[k][j]){r=k;break;} if(a.f[r][j]) { if(r!=i)for(k=0;k<=n+1;k++)swap(a.f[r][k],a.f[i][k]); for(u=i+1;u<=m;u++)if(a.f[u][j]) for(k=i;k<=n+1;k++)a.f[u][k]^=a.f[i][k]; i++; } j++; } for(u=i;u<=m;u++)//判断无解 if(a.f[u][n+1])return -1; return i-1;}int main(){ int T,tt=0; cin>>T; while(T--) { int i,j,k,n,m,a,b,q,r; cin>>n>>m; memset(e.f,0,sizeof(e.f)); for(i=1;i<=m;i++) { cin>>k; for(j=0;j<k;j++) { cin>>a; e.f[a][i]=1; } } cout<<"Case "<<++tt<<":"<<endl; cin>>q; while(q--) { for(i=1;i<=n;i++) { cin>>a; e.f[i][m+1]=a; } r=find(e,n,m);//求出有界遍历个数r if(r==-1)cout<<0<<endl; else cout<<(1LL<<(m-r))<<endl;//注意范围,超int } } return 0;}/* 设m个开关状态为xi(1<=i<=m,0<=xi<=1),可列m元一次方程组。用高斯消元法求得自由变量个数k。答案就是2^k*/