NC51315. Steady Cow Assignment
描述
输入描述
Line 1: Two space-separated integers, N and B
Lines 2..N+1: Each line contains B space-separated integers which are exactly 1..B sorted into some order. The first integer on line i+1 is the number of the cow i's top-choice barn, the second integer on that line is the number of the i'th cow's second-choice barn, and so on.
Line N+2: B space-separated integers, respectively the capacity of the first barn, then the capacity of the second, and so on. The sum of these numbers is guaranteed to be at least N.
输出描述
Line 1: One integer, the size of the minumum range of barn rankings the cows give their assigned barns, including the endpoints.
示例1
输入:
6 4 1 2 3 4 2 3 1 4 4 2 3 1 3 1 2 4 1 3 4 2 1 4 2 3 2 1 3 2
输出:
2
C++ 解法, 执行用时: 90ms, 内存消耗: 548K, 提交时间: 2021-08-17 18:07:19
#include<bits/stdc++.h> using namespace std; const int maxn = 1010; int maps[maxn][22], vis[22], used[22][maxn]; int link[22], limit[22], n, m, s, e, mid; bool Find (int u) { for (int i=1; i<=m; i++) {//多重匹配 if (!vis[i] && maps[u][i]<e && s<=maps[u][i]) { vis[i] = 1; if (link[i] < limit[i]) {//i棚子未满 used[i][link[i] ++] = u; return true; } for (int j=0; j<limit[i]; j++)//i棚子已满,寻找增广路 if (Find(used[i][j])) { used[i][j] = u; return true; } } } return false; } bool hungry () { for (s=1; s<=m+1-mid; s++) {//枚举区间起点与终点 int ans = 0; e = s + mid; memset (link, 0, sizeof(link)); for (int i=1; i<=n; i++) { memset (vis, 0, sizeof(vis)); if (Find (i)) ans ++; } if (ans == n) return true; } return false; } int main () { while (scanf ("%d %d", &n, &m) != EOF) { for (int i=1; i<=n; i++) for (int j=1; j<=m; j++) { scanf ("%d", &mid); maps[i][mid] = j; } for (int i=1; i<=m; i++) scanf ("%d", &limit[i]); int left = 1, right = m, ans = 0; while (left<=right) {//二分枚举区间 mid = (right+left)/2; if (hungry()) { ans = mid; right = mid - 1 ; } else left = mid + 1 ; } printf ("%d\n", ans); } return 0; }