Problem: T-Shirt Gumbo
Description: 一群运动员他们对自己T恤的尺码有一个范围的要求。现在给出5种尺码的衣服的数量,问每个运动员是否都能选到自己满意的尺码的衣服。
Solution: 这个题一看就是二分图的多重匹配,但是我一开始是不知道的,于是我就用了二分图的最大匹配来做,我们不要看种类,直接看每一件衣服,这样就转化成了每个运动员都能选到衣服。
Code(最大匹配):
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
const int M = 200;
int n, m;
int num[10];
vector<int> map[25];
int belong[M];
bool used[M];
int getnum(char s)
{
if (s == 'S')
return 1;
if (s == 'M')
return 2;
if (s == 'L')
return 3;
if (s == 'X')
return 4;
if (s == 'T')
return 5;
return 0;
}
bool dfs(int s)
{
for (int i = 0; i < map[s].size(); i++) {
int end = map[s].at(i);
if (used[end])
continue;
used[end] = true;
if (belong[end] == -1 || dfs(belong[end])) {
belong[end] = s;
return true;
}
}
return false;
}
int main()
{
string str;
while (cin >> str, str.at(0) != 'E') {
for (int i = 0; i < 25; i++)
map[i].clear();
cin>>n;
string edge[25];
int sum = 0, x;
for (int i = 1; i <= n; i++)
cin >> edge[i];
for (int i = 1; i <= 5; i++)
cin >> x,
num[i] = sum, sum += x;
num[6] = sum;
cin>>str;
if (sum < n) {
cout << "I'd rather not wear a shirt anyway..." << endl;
continue;
}
for (int i = 1; i <= n; i++) {
int start = num[getnum(edge[i].at(0))];
int end = num[getnum(edge[i].at(1)) + 1];
for (int j = start + 1; j <= end; j++)
map[i].push_back(j);
}
int ans = 0;
memset(belong, -1, sizeof(belong));
for (int i = 1; i <= n; i++) {
memset(used, false, sizeof(used));
if (dfs(i))
++ans;
}
if (ans == n)
cout << "T-shirts rock!";
else
cout << "I'd rather not wear a shirt anyway...";
cout << endl;
}
return 0;
}
Code(多重匹配):
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
const int M = 20;
int n, m;
int num[10];
vector<int> map[25];
int belong[M][M];
int used[M];
int getnum(char s)
{
if (s == 'S')
return 1;
if (s == 'M')
return 2;
if (s == 'L')
return 3;
if (s == 'X')
return 4;
if (s == 'T')
return 5;
return 0;
}
bool dfs(int s)
{
for (int i = 0; i < map[s].size(); i++) {
int end = map[s].at(i);
if (used[end] >= num[end])
continue;
++used[end];
for (int j = 1; j <= num[end]; j++)
if (belong[end][j] == -1 || dfs(belong[end][j])) {
belong[end][j] = s;
return true;
}
}
return false;
}
int main()
{
string str;
while (cin >> str, str.at(0) != 'E') {
for (int i = 0; i < 25; i++)
map[i].clear();
cin>>n;
int sum = 0;
for (int i = 1; i <= n; i++) {
cin >> str;
int start = getnum(str.at(0));
int end = getnum(str.at(1));
for (int j = start; j <= end; j++)
map[i].push_back(j);
}
for (int i = 1; i <= 5; i++)
cin >> num[i], sum += num[i];
cin>>str;
if (sum < n) {
cout << "I'd rather not wear a shirt anyway..." << endl;
continue;
}
int ans = 0;
memset(belong, -1, sizeof(belong));
for (int i = 1; i <= n; i++) {
memset(used, 0, sizeof(used));
if (dfs(i))
++ans;
}
if (ans == n)
cout << "T-shirts rock!";
else
cout << "I'd rather not wear a shirt anyway...";
cout << endl;
}
return 0;
}