1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| #include <bits/stdc++.h> using namespace std; typedef long long ll; const int mod = 998244353; const int N = 50, M = 10000000; char g[N][N]; int n, f[N], ans; int sz[N], id[N], lg[M], len, cnt = 0, fb[N], le[M]; int nw[M], mu[M];
inline int add(const int &x, const int &y) { return x + y < mod ? x + y : x + y - mod; } inline int sub(const int &x, const int &y) { return x - y < 0 ? x - y + mod : x - y; } inline int mul(const int &x, const int &y) { return(int)((ll)x * y % mod); } int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); } void fwt(int *A, int lmt, int opt) { for(int mid = 1; mid < lmt; mid <<= 1) for(int j = 0; j < lmt; j += mid << 1) for(int k = 0; k < mid; k++) { if(opt == 1) A[j + mid + k] = add(A[j + mid + k], A[j + k]); else A[j + mid + k] = sub(A[j + mid + k], A[j + k]); } } int main() { scanf("%d", &n); for(int i = 1; i <= n; i++) f[i] = i; for(int i = 1; i <= n; i++) { scanf("%s", g[i] + 1); for(int j = 1; j <= n; j++) if(g[i][j] == 'A') f[find(i)] = find(j); } for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) if(g[i][j] == 'X' && find(i) == find(j)) { puts("-1"); return 0; } ans = n - 1; for(int i = 1; i <= n; i++) ++sz[find(i)]; for(int i = 1; i <= n; i++) if(find(i) == i && sz[i] > 1) id[i] = cnt, lg[1 << cnt] = cnt, ++cnt; if(!cnt) { printf("%d\n", ans); return 0; } len = (1 << cnt); for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) { if(g[i][j] != 'X') continue; if(sz[find(i)] > 1 && sz[find(j)] > 1) { fb[id[find(i)]] |= (1 << id[find(j)]); fb[id[find(j)]] |= (1 << id[find(i)]); } } le[0] = 1; for(int i = 0; i < cnt; i++) le[1 << i] = 1; for(int i = 0; i < len; i++) { if(le[i]) continue; int x = lg[i & -i], y = i - (1 << x); if(le[y] && (fb[x] & y) == 0) le[i] = 1; } fwt(le, len, 1); mu[0] = (cnt & 1) ? -1 : 1; for(int i = 1; i < len; i++) mu[i] = sub(0, mu[i ^ (i & -i)]); for(int i = 0; i < len; i++) nw[i] = le[i]; for(int i = 1;; i++) { int z = 0; for(int j = 0; j < len; j++) z = add(z, mul(mu[j], nw[j])); if(z) { printf("%d\n", ans + i); break; } for(int j = 0; j < len; j++) nw[j] = mul(nw[j], le[j]); } return 0; }
|