PKU 2584 - T-Shirt Gumbo (二分图最大匹配 & 匈牙利算法 | 最大流 & EK)

题意

给出一个人能穿的型号和每个型号衣服的多少,求能不能每个人恰好分配到一件。

思路

第一次先用最大流写了一下,然后就试试最大匹配。

最大匹配就是把n件相同的衣服拆成一件一件,分别编号,再把人和它们相连,然后就匈牙利算法了。 
感觉用最大匹配写繁琐一点。

被注释部分是最大流的

代码

  
  
  
  
  1. #include <cstdio>
  2. #include <stack>
  3. #include <set>
  4. #include <iostream>
  5. #include <string>
  6. #include <vector>
  7. #include <queue>
  8. #include <functional>
  9. #include <cstring>
  10. #include <algorithm>
  11. #include <cctype>
  12. #include <string>
  13. #include <map>
  14. #include <cmath>
  15. #define LL long long
  16. #define SZ(x) (int)x.size()
  17. #define Lowbit(x) ((x) & (-x))
  18. #define MP(a, b) make_pair(a, b)
  19. #define MS(arr, num) memset(arr, num, sizeof(arr))
  20. #define PB push_back
  21. #define F first
  22. #define S second
  23. #define ROP freopen("input.txt", "r", stdin);
  24. #define MID(a, b) (a + ((b - a) >> 1))
  25. #define LC rt << 1, l, mid
  26. #define RC rt << 1|1, mid + 1, r
  27. #define LRT rt << 1
  28. #define RRT rt << 1|1
  29. #define BitCount(x) __builtin_popcount(x)
  30. const double PI = acos(-1.0);
  31. const int INF = 0x3f3f3f3f;
  32. using namespace std;
  33. const int MAXN = 100 + 10;
  34. const int MOD = 1e9 + 7;
  35. const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
  36. typedef pair<int, int> pii;
  37. typedef vector<int>::iterator viti;
  38. typedef vector<pii>::iterator vitii;
  39. string str = "0SMLXT";
  40. struct EDGES
  41. {
  42. int from, to;
  43. };
  44. struct EDGE
  45. {
  46. int from, to, cap, flow;
  47. };
  48. int start[6], cnt[6], L[MAXN], R[MAXN];
  49. int link[MAXN], vis[MAXN], head[MAXN], next[MAXN * MAXN];
  50. struct BIMATCHING
  51. {
  52. vector<EDGES> edges;
  53. void init()
  54. {
  55. MS(link, -1); MS(head, -1);
  56. edges.clear();
  57. }
  58. void add_edge(int from, int to)
  59. {
  60. edges.PB((EDGES){from, to});
  61. int m = SZ(edges);
  62. next[m - 1] = head[from];
  63. head[from] = m - 1;
  64. }
  65. bool dfs(int u)
  66. {
  67. for (int i = head[u]; i != -1; i = next[i])
  68. {
  69. EDGES &e = edges[i];
  70. int v = e.to;
  71. if (!vis[v])
  72. {
  73. vis[v] = 1;
  74. if (link[v] == -1 || dfs(link[v]))
  75. {
  76. link[v] = u;
  77. return true;
  78. }
  79. }
  80. }
  81. return false;
  82. }
  83. int hungary(int n)
  84. {
  85. int res = 0;
  86. for (int i = 6; i < 6 + n; i++)
  87. {
  88. MS(vis, 0);
  89. if (dfs(i)) res++;
  90. }
  91. return res;
  92. }
  93. }hun;
  94. /*
  95. struct MAXFLOW
  96. {
  97. int head[MAXN], next[MAXN * MAXN], N, a[MAXN], p[MAXN];
  98. vector<EDGE> edges;
  99. void init(int N)
  100. {
  101. this->N = N;
  102. MS(head, -1);
  103. edges.clear();
  104. }
  105. void add_edge(int from, int to, int cap)
  106. {
  107. edges.PB((EDGE){from, to, cap, 0});
  108. edges.PB((EDGE){to, from, 0, 0});
  109. int m = SZ(edges);
  110. next[m - 2] = head[from];
  111. head[from] = m - 2;
  112. next[m - 1] = head[to];
  113. head[to] = m - 1;
  114. }
  115. void EK(int st, int &flow)
  116. {
  117. queue<int> qu;
  118. while (true)
  119. {
  120. MS(a, 0);
  121. a[0] = INF;
  122. qu.push(st);
  123. while (!qu.empty())
  124. {
  125. int u = qu.front(); qu.pop();
  126. for (int i = head[u]; i != -1; i = next[i])
  127. {
  128. EDGE &e = edges[i];
  129. if (!a[e.to] && e.cap > e.flow)
  130. {
  131. a[e.to] = min(a[u], e.cap - e.flow);
  132. qu.push(e.to);
  133. p[e.to] = i;
  134. }
  135. }
  136. }
  137. if (!a[N]) break;
  138. int u = N;
  139. while (u != st)
  140. {
  141. edges[p[u]].flow += a[N];
  142. edges[p[u] ^ 1].flow -= a[N];
  143. u = edges[p[u]].from;
  144. }
  145. flow += a[N];
  146. }
  147. }
  148. }maxFlow;
  149. */
  150. int main()
  151. {
  152. //ROP;
  153. string cmd;
  154. int i, j;
  155. while (cin >> cmd && cmd != "ENDOFINPUT")
  156. {
  157. int n;
  158. cin >> n;
  159. //int N = n + 5 + 1;
  160. //maxFlow.init(N);
  161. hun.init();
  162. string sz;
  163. for (i = 6; i <= n + 5; i++)
  164. {
  165. cin >> sz;
  166. int l = str.find(sz[0]);
  167. int r = str.find(sz[1]);
  168. L[i] = l, R[i] = r;
  169. /*
  170. for (j = l; j <= r; j++) maxFlow.add_edge(j, i, 1);
  171. maxFlow.add_edge(i, N, 1);
  172. */
  173. }
  174. int sum = 0;
  175. for (i = 1; i <= 5; i++)
  176. {
  177. int num;
  178. cin >> num;
  179. start[i] = sum + 1;
  180. cnt[i] = num;
  181. sum += cnt[i];
  182. //maxFlow.add_edge(0, i, num);
  183. }
  184. for (i = 6; i < 6 + n; i++)
  185. for (j = start[L[i]]; j < start[R[i]] + cnt[R[i]]; j++) hun.add_edge(i, j);
  186. cin >> cmd;
  187. int flow = hun.hungary(n);
  188. //maxFlow.EK(0, flow);
  189. printf("%s\n", (flow == n ? "T-shirts rock!" : "I'd rather not wear a shirt anyway..."));
  190. }
  191. return 0;
  192. }

你可能感兴趣的:(ACM,pku)