Codeforces 575C 状压+KM
2015-09-08 10:53
288 查看
题解链接:http://www.cygmasot.com/index.php/2015/09/08/codeforces_575c/
链接
题意:
给定n个人,把n个人分成周日上班和周六上班两批人。
一共有n个岗位。一个人对应一个岗位
第一个矩阵 i-th, j-th 意思是第i个人在周六上班 且任职第j个岗位的开心度。
第二个矩阵就是第i个人在周日上班 且任职第j个岗位的开心度。
求最大的开心度
思路:
枚举哪些人在第一批。然后KM。
=-=加个时限的黑科技。。
链接
题意:
给定n个人,把n个人分成周日上班和周六上班两批人。
一共有n个岗位。一个人对应一个岗位
第一个矩阵 i-th, j-th 意思是第i个人在周六上班 且任职第j个岗位的开心度。
第二个矩阵就是第i个人在周日上班 且任职第j个岗位的开心度。
求最大的开心度
思路:
枚举哪些人在第一批。然后KM。
=-=加个时限的黑科技。。
#include <map> #include <iostream> #include <cstring> #include <string> #include <algorithm> #include <cstdio> #include <queue> #include <cmath> #include <set> #include <stdio.h> #include <ctime> using namespace std; template <class T> inline bool rd(T &ret) { char c; int sgn; if (c = getchar(), c == EOF) return 0; while (c != '-' && (c<'0' || c>'9')) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return 1; } template <class T> inline void pt(T x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) pt(x / 10); putchar(x % 10 + '0'); } typedef pair<int, int> pii; const int inf = 1e9; const int N = 22; const int M = N; int ans; struct KM { int n, w[M][M]; int lx[M], ly[M], match[M], slack[M]; bool s[M], t[M]; inline bool hungary(int x) { s[x] = true; for (int y = 0; y < n; ++y) if (!t[y] && lx[x] + ly[y] == w[x][y]) { t[y] = true; if (match[y] == -1 || hungary(match[y])) { match[y] = x; return true; } } else slack[y] = min(slack[y], lx[x] + ly[y] - w[x][y]); return false; } inline int rediculous() { int magic; magic = 0; for (int i = 0; i < n; ++i) { lx[i] = *max_element(w[i], w[i] + n); magic += lx[i]; } if (magic <= ans) return 0; memset(match, -1, n << 2); memset(ly, 0, n << 2); for (register int i = 0; i < n; ++i) { for (;;) { memset(s, 0, n); memset(t, 0, n); memset(slack, 0x7f, n << 2); if (hungary(i)) break; else { int a = inf; for (register int j = 0; j < n; ++j) if (!t[j] && slack[j] < a) a = slack[j]; magic = 0; for (register int j = 0; j < n; ++j) { if (s[j]) lx[j] -= a; if (t[j]) ly[j] += a; magic += lx[j] + ly[j]; } if (magic <= ans) { return 0; } } } } ans = magic; return magic; } } S; int n; int a , b ; int CNT(int x) { int siz = 0; while (x) { siz += x & 1; x >>= 1; } return siz; } int main() { clock_t lim = clock() + 1.9*CLOCKS_PER_SEC; rd(n); S.n = n; for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)rd(a[i][j]); for (int i = 0; i < n; i++)for (int j = 0; j < n; j++) rd(b[i][j]); ans = 0; for (int i = 0; i < 1 << n; ++i) if (CNT(i) == (n >> 1)) { for (int j = 0; j < n; j++) if (i&(1 << j)) memcpy(S.w[j], a[j], n<<2); else memcpy(S.w[j], b[j], n<<2); ans = max(ans, S.rediculous()); if (clock() >= lim)break; } pt(ans); return 0; }
相关文章推荐