[洛谷P2210]Haywire
题目大意:有$n(n\leqslant12)$个数,每个数和其他三个数连边,求一个排列,使得边的长度最小
题解:状压$DP$,$f_{i,j}$表示当前确定的数状态为$i$,有$j$条边起点被确定终点没有确定的最短距离
卡点:无
C++ Code:
#include <cstdio> #define maxn 13 int n, m; int s[maxn][3]; int f[1 << maxn][maxn * 3]; inline int min(int a, int b) {return a < b ? a : b;} int main() { scanf("%d", &n); for (int i = 0; i < n; i++){ scanf("%d%d%d", s[i], s[i] + 1, s[i] + 2); s[i][0]--, s[i][1]--, s[i][2]--; } int U = 1 << n; __builtin_memset(f, 0x3f, sizeof f); f[0][0] = 0; for (int i = 0; i < U; i++) { for (int j = 0; j < n; j++) if (!(i & 1 << j)){ for (int k = 0; k <= n * 3; k++) { int tmp = k; if (i & 1 << s[j][0]) tmp--; else tmp++; if (i & 1 << s[j][1]) tmp--; else tmp++; if (i & 1 << s[j][2]) tmp--; else tmp++; f[i | 1 << j][tmp] = min(f[i | 1 << j][tmp], f[i][k] + tmp); } } } printf("%d\n", f[U - 1][0]); return 0; }