hdu3364 Lanterns 高斯消元

来源:互联网 发布:python的入门书 知乎 编辑:程序博客网 时间:2024/05/16 19:35
//有m个开关,n个灯泡,每个开关可以控制不同的灯泡(可以有多个)
//给定n个灯泡的亮暗情况,问有多少种开关的情况
//用a[i][j]表示第j个开关对第i个灯泡能否控制,1为能,0为否
//用高斯消元,ans = 2^(var-k) ,(var-k)为自由变量数
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn =  60 ;
#define abs(a) (a > 0 ? a : -a)
typedef __int64 ll ;
int a[maxn][maxn] ;
int b[maxn][maxn] ;
int x[maxn] ;
int free_x[maxn] ;
int  equ , var;
int Gauss()
{
    memset(free_x , 0 , sizeof(free_x)) ;
    int free_num , free_idex ;
    int col = 0 ;int k ;
    for(k = 0;k < equ && col < var;k++,col++)
    {
        int max_r = k ;
        for(int i = k+1;i < equ ;i++)
        if(abs(a[max_r][col])< abs(a[i][col]))
        max_r = i ;
        if(max_r != k)
        for(int j = 0;j <= var;j++)
        swap(a[max_r][j] , a[k][j]) ;
        if(a[k][col] == 0){k--;continue ;}
        for(int i = k+1 ; i < equ ;i++)
        {
            if(a[i][col] == 0)continue ;
            for(int j = col ; j <= var;j++)
            a[i][j] ^= a[k][j] ;
        }
    }
    for(int i = k ;i < equ ;i++)
    if(a[i][col] != 0)return -1 ;//无解
    return var - k ;
}




int main()
{
    //freopen("in.txt" , "r" , stdin) ;
    int T ;int cas =0 ;
    scanf("%d" , &T) ;
    while(T--)
    {
        scanf("%d%d" , &equ , &var) ;
        memset(a , 0 , sizeof(a)) ;
        for(int i = 0;i < var;i++)
        {
            int num ;
            scanf("%d" , &num) ;
            while(num--)
            {
                int t ;
                scanf("%d" , &t) ;
                a[t-1][i] = 1;
            }
        }
        int q ;
        for(int i = 0 ;i < equ ;i++)
        memcpy(b[i] , a[i] , sizeof(a[i])) ;
        scanf("%d" , &q) ;
        printf("Case %d:\n" , ++cas) ;
        while(q--)
        {
            for(int i = 0 ;i < equ ;i++)
            {
                int t ;
                scanf("%d" , &t) ;
                b[i][var] = t ;
            }
            for(int i = 0 ;i < equ;i++)
            memcpy(a[i] , b[i] , sizeof(b[i])) ;
            int sum = Gauss() ;
            if(sum < 0){puts("0");continue ;}
            ll ans = 1;
            for(int i = 1;i <= sum;i++)
            ans*=2;
            printf("%I64d\n" , ans) ;
        }
    }
    return  0 ;
}



0 0
原创粉丝点击