UVa 11045 - My T-shirt suits me(最大流)

题意

一个人有两种合适的T恤,现在有K套,问能不能让所有人穿上合适的。

思路

乍一看感觉是二分图匹配的内容?可是我不会。

可以这么想:建一个源点,到每个衣服的容量显然可以算出。每个衣服到每个合适的人的容量为1,每个人最后都连上汇点,这条路容量为1(因为只能穿一件)。如果最后流量能达到人数,说明可以,否则不可以。

把最大流封装了一下。

代码

  
  
  
  
  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 <ctime>
  13. #include <cstdlib>
  14. #include <fstream>
  15. #include <string>
  16. #include <sstream>
  17. #include <map>
  18. #include <cmath>
  19. #define LL long long
  20. #define SZ(x) (int)x.size()
  21. #define Lowbit(x) ((x) & (-x))
  22. #define MP(a, b) make_pair(a, b)
  23. #define MS(arr, num) memset(arr, num, sizeof(arr))
  24. #define PB push_back
  25. #define F first
  26. #define S second
  27. #define ROP freopen("input.txt", "r", stdin);
  28. #define MID(a, b) (a + ((b - a) >> 1))
  29. #define LC rt << 1, l, mid
  30. #define RC rt << 1|1, mid + 1, r
  31. #define LRT rt << 1
  32. #define RRT rt << 1|1
  33. #define BitCount(x) __builtin_popcount(x)
  34. const double PI = acos(-1.0);
  35. const int INF = 0x3f3f3f3f;
  36. using namespace std;
  37. const LL MAXN = 30 + 10;
  38. const int MOD = 20071027;
  39. typedef pair<int, int> pii;
  40. typedef vector<int>::iterator viti;
  41. typedef vector<pii>::iterator vitii;
  42. int Convert(string str)
  43. {
  44. if (str == "XXL") return 1;
  45. else if (str == "XL") return 2;
  46. else if (str == "L") return 3;
  47. else if (str == "M") return 4;
  48. else if (str == "S") return 5;
  49. else if (str == "XS") return 6;
  50. }
  51. struct EDGE
  52. {
  53. int from, to, cap, flow;
  54. };
  55. struct MAXFLOW
  56. {
  57. int a[MAXN], p[MAXN], N;
  58. vector<EDGE> edge;
  59. vector<int> G[MAXN];
  60. void init(int n)
  61. {
  62. this->N = n;
  63. for (int i = 0; i <= n; i++) G[i].clear();
  64. }
  65. void add_edge(int from, int to, int cap)
  66. {
  67. edge.PB((EDGE){from, to, cap, 0});
  68. edge.PB((EDGE){to, from, 0, 0});
  69. int m = SZ(edge);
  70. G[from].PB(m - 2);
  71. G[to].PB(m - 1);
  72. }
  73. void EK(int st, int &flow)
  74. {
  75. queue<int> qu;
  76. while (true)
  77. {
  78. MS(a, 0);
  79. a[0] = INF;
  80. qu.push(0);
  81. while (!qu.empty())
  82. {
  83. int u = qu.front(); qu.pop();
  84. for (int i = 0; i < SZ(G[u]); i++)
  85. {
  86. EDGE &e = edge[G[u][i]];
  87. if (!a[e.to] && e.cap > e.flow)
  88. {
  89. qu.push(e.to);
  90. p[e.to] = G[u][i];
  91. a[e.to] = min(a[u], e.cap - e.flow);
  92. }
  93. }
  94. }
  95. if (!a[N]) break;
  96. int u = N;
  97. while (u != st)
  98. {
  99. edge[p[u]].flow += a[N];
  100. edge[p[u] ^ 1].flow -= a[N];
  101. u = edge[p[u]].from;
  102. }
  103. flow += a[N];
  104. }
  105. }
  106. }maxFlow;
  107. int main()
  108. {
  109. //ROP;
  110. ios::sync_with_stdio(0);
  111. int T, i, j, nmax, npeo;
  112. cin >> T;
  113. while (T--)
  114. {
  115. cin >> nmax >> npeo;
  116. maxFlow.init(npeo + 6 + 1);
  117. int f = nmax / 6;
  118. string s, ss;
  119. for (i = 1; i <= npeo; i++)
  120. {
  121. cin >> s;
  122. int tmp = Convert(s);
  123. maxFlow.add_edge(tmp, i + 6, 1);
  124. cin >> s;
  125. tmp = Convert(s);
  126. maxFlow.add_edge(tmp, i + 6, 1);
  127. }
  128. for (i = 1; i <= 6; i++) maxFlow.add_edge(0, i, f);
  129. for (i = 7; i <= npeo + 6; i++) maxFlow.add_edge(i, npeo + 6 + 1, 1);
  130. f = 0;
  131. maxFlow.EK(0, f);
  132. if (f == npeo) puts("YES");
  133. else puts("NO");
  134. }
  135. return 0;
  136. }

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