做法:高斯消元解异或方程组,或折半搜索都可以过啦。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <cstdlib> 5 #define LL long long 6 using namespace std; 7 LL m[60][60]; 8 int n, M, b[60], ans, Ans[60]; 9 10 void Init() 11 { 12 scanf("%d%d", &n, &M); 13 for (int i = 1; i <= n; i++) 14 m[i][i] = 1, b[i] = 1; 15 for (int i = 1; i <= M; i++) 16 { 17 int u, v; 18 scanf("%d%d", &u, &v); 19 m[u][v] = 1; 20 m[v][u] = 1; 21 } 22 } 23 24 void Dfs(int dep, int count) 25 { 26 if (count >= ans) return; 27 if (dep == 0) 28 { 29 if (count < ans) ans = count; 30 return; 31 } 32 if (m[dep][dep]) 33 { 34 bool now = b[dep]; 35 for (int i = dep + 1; i <= n; i++) 36 if (m[dep][i]) now ^= Ans[i]; 37 Ans[dep] = now; 38 if (Ans[dep]) Dfs(dep - 1, count + 1); 39 else Dfs(dep - 1, count); 40 } 41 else 42 { 43 Ans[dep] = 0; Dfs(dep - 1, count); 44 Ans[dep] = 1; Dfs(dep - 1, count + 1); 45 Ans[dep] = 0; 46 } 47 } 48 49 void Swap(int l, int r) 50 { 51 for (int i = 1; i <= n; i++) 52 swap(m[l][i], m[r][i]); 53 swap(b[l], b[r]); 54 } 55 56 void Xor(int l, int r) 57 { 58 for (int i = 1; i <= n; i++) 59 m[l][i] ^= m[r][i]; 60 b[l] ^= b[r]; 61 } 62 63 void Work() 64 { 65 for (int k = 1; k <= n; k++) 66 { 67 bool flag = 0; 68 for (int i = k; i <= n; i++) 69 if (m[i][k]) 70 { 71 flag = 1; 72 Swap(i, k); 73 break; 74 } 75 if (flag == 0) continue; 76 for (int i = k + 1; i <= n; i++) 77 if (m[i][k]) Xor(i, k); 78 } 79 } 80 81 int main() 82 { 83 Init(); 84 Work(); 85 ans = 10000000; 86 Dfs(n, 0); 87 printf("%d", ans); 88 }
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #define N 40 5 #define M 100007 6 #define LL long long 7 using namespace std; 8 int n, m, tot, g[M + 1], ans = M; 9 LL h[M + 1], Ans, a[N], S[40]; 10 11 void Pre_work() 12 { 13 S[0] = 1; 14 for (int i = 1; i <= 39; i++) S[i] = S[i - 1] * 2; 15 } 16 17 void Init() 18 { 19 Pre_work(); 20 scanf("%d%d", &n, &m); 21 int u, v; 22 for (int i = 1; i <= n; i++) 23 a[i] |= S[i]; 24 for (int i = 1; i <= m; i++) 25 { 26 scanf("%d%d", &u, &v); 27 a[u] |= S[v]; 28 a[v] |= S[u]; 29 } 30 Ans = S[n + 1] - 2; 31 } 32 33 int Hash(LL x) 34 { 35 int p = x % M; 36 for (; h[p] != 0 && h[p] != x; p = (p + 1) % M); 37 return p; 38 } 39 40 void Dfs(int dep, LL num, int step) 41 { 42 if (dep > tot) 43 { 44 if (num == Ans) ans = min(ans, step); 45 int site = Hash(num); 46 if (!h[site]) h[site] = num, g[site] = step; 47 else g[site] = g[site] < step ? g[site] : step; 48 return; 49 } 50 Dfs(dep + 1, num ^ a[dep], step + 1); 51 Dfs(dep + 1, num, step); 52 } 53 54 void dfs(int dep, LL num, int step) 55 { 56 if (dep > n) 57 { 58 if (num == Ans) ans = min(ans, step); 59 LL p = Ans ^ num; 60 int site = Hash(p); 61 if (h[site]) ans = min(ans, g[site] + step); 62 return; 63 } 64 dfs(dep + 1, num ^ a[dep], step + 1); 65 dfs(dep + 1, num, step); 66 } 67 68 int main() 69 { 70 Init(); 71 tot = n / 2; 72 Dfs(1, 0, 0); 73 dfs(tot + 1, 0, 0); 74 printf("%d", ans); 75 }