您的位置:首页 > 其它

poj1830 开关问题

2017-07-04 19:11 218 查看
传送门

高斯消元。

对于每一个开关都有两种选择,我们只需要对于每个开关以及对应结果用高斯消元求解亦或方程即可,有多少自由元答案就是2的几次方。

好像用bitset会更快,但是并不会用,改天学学。

CODE:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int f[50][50];
int T,n,x,y;
inline int gauss()
{
int ans=0;
for(int i=1;i<=n;i++)
{
if(!f[i][i])
{
int p=i;
for(int j=i+1;j<=n;j++)
if(f[j][i]){p=j;break;}
if(p!=i) for(int j=1;j<=n+1;j++)
swap(f[p][j],f[i][j]);
}
if(!f[i][i]){ans++;continue;}
for(int j=1;j<=n;j++)
if(j!=i&&f[j][i]) for(int k=1;k<=n+1;k++)
f[j][k]^=f[i][k];
}
for(int i=1;i<=n;i++)
{
bool all=1;
for(int j=1;j<=n;j++)
if(f[i][j]){all=0;break;}
if(all&&f[i][n+1]) return -1;
}
return ans;
}
int main()
{
scanf("%d",&T);
while(T--)
{
memset(f,0,sizeof(f));
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&f[i][n+1]);
for(int i=1;i<=n;i++)
scanf("%d",&x),f[i][n+1]^=x;
scanf("%d%d",&x,&y);
while(x&&y) f[y][x]=1,scanf("%d%d",&x,&y);
for(int i=1;i<=n;i++)
f[i][i]=1;
int ans=gauss();
if(ans==-1) printf("Oh,it's impossible~!!\n");
else printf("%d\n",1<<ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息