题目大意:
有
n(n≤200)
个格子,每个格子为黑色或白色。我们点击每个格子,所有与之相关的格子均会反色。求出一种方案使得所有格子的颜色一样。
分析:
首先敲击格子的顺序是无关紧要的,然后
n
<script type="math/tex" id="MathJax-Element-170">n</script>又这么小,很明显就是高斯消元了。
AC code:
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#define pb push_back
using namespace std;
const int MAXN = 209;
int n;
int ch[MAXN], pl[MAXN];
int g[MAXN][MAXN];
int s[MAXN][MAXN];
vector<int> ans;
bool check(int p)
{
int m = n+1;
memcpy(s, g, sizeof g);
for(int i = 1; i <= n; ++i)
s[i][m] ^= p;
int j = 1;
for(int i = 1; i <= n; ++i)
{
bool flag = false;
for(int k = j; k <= n; ++k)
if(s[k][i])
{
for(int t = 1; t <= m; ++t)
swap(s[k][t], s[j][t]);
flag = true;
break;
}
if(!flag) continue;
for(int k = 1; k <= n; ++k)
if(k != j && s[k][i])
for(int t = 1; t <= m; ++t)
s[k][t] ^= s[j][t];
pl[j++] = i;
}
for(int i = j; i <= n; ++i)
if(s[i][m])
return false;
memset(ch, 0, sizeof ch);
for(int i = 1; i <= j; ++i)
if(s[i][m]) ch[pl[i]] = 1;
return true;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
{
int tmp, x;
scanf("%d", &tmp);
while(tmp--)
{
scanf("%d", &x);
g[x][i] = 1;
}
}
for(int i = 1; i <= n; ++i)
scanf("%d", &g[i][n+1]);
if(check(0) || check(1))
{
for(int i = 1; i <= n; ++i)
if(ch[i]) ans.pb(i);
printf("%d\n", ans.size());
for(int i = 0, sz = ans.size(); i < sz; ++i)
printf("%d ", ans[i]);
puts("");
}
else puts("-1");
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}