题目链接请戳 这里
解题思路:
二分图匹配用求最大流EK算法解决
可以把每件衣服都表示成一个节点,每当一个人可以和某种衣服匹配则与这种型号的所有衣服有容量为1的通道。
代码
#include<stdio.h> #include<string.h> #include<queue> #define N 1200 #define INF 1e9 using namespace std; int Cap[N][N], Flow[N][N]; int a[N], Pre[N]; int n, m; //对衣服编码 int code(char ss[]) { int step = n / 6; if (strcmp(ss, "XXL") == 0) { return 1; } else if (strcmp(ss, "XL") == 0) { return step + 1; } else if (strcmp(ss, "L") == 0) { return 2 * step + 1; } else if (strcmp(ss, "M") == 0) { return 3 * step + 1; } else if (strcmp(ss, "S") == 0) { return 4 * step + 1; } else if (strcmp(ss, "XS") == 0) { return 5 * step + 1; } } int EK(int s, int t) { queue<int> q; memset(Flow, 0, sizeof(Flow)); int f = 0; while (1) { memset(a, 0, sizeof(a)); a[s] = INF; q.push(s); while (!q.empty()) { int u = q.front(); q.pop(); for (int v = s; v <= t; v++) if (!a[v] && Cap[u][v] > Flow[u][v]) { Pre[v] = u; q.push(v); a[v] = min(a[u], Cap[u][v] - Flow[u][v]); } } if (a[t] == 0) break; for (int u = t; u != s; u = Pre[u]) { Flow[Pre[u]][u] += a[t]; Flow[u][Pre[u]] -= a[t]; } f += a[t]; } return f; } int main() { int t; scanf("%d", &t); while (t--) { memset(Cap, 0, sizeof(Cap)); scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++) { char s1[10], s2[10]; scanf("%s%s", s1, s2); int n1 = code(s1); int n2 = code(s2); for (int j = 0; j < n / 6; j++) { Cap[i][m + n1 + j] = 1; Cap[i][m + n2 + j] = 1; } } //处理超级汇点和超级聚点 for (int i = 1; i <= m; i++) Cap[0][i] = 1; for (int i = 1; i <= n; i++) Cap[m + i][n + m + 1] = 1; //最大流的结果就是最多能匹配的人数 int res = EK(0, n + m + 1); if (res == m) printf("YES\n"); else printf("NO\n"); } return 0; }
时间: 2024-10-21 01:41:00