题目大意:n个人,5种型号的T恤,给出每个人能够穿的T恤范围,以及5种T恤的数量,问能否使得每个人都能够穿上T恤。
明显的匹配问题。
建图:
X集合为n个人,Y集合为T恤。若第i个人能够穿第j件T恤,则两者连一条边,得到一个二分图。问题转化为求最大匹配,看最大匹配数是否等于n。
#include<iostream>
#include<vector>
#include<cstdio>
#include<map>
#include<cstring>
using namespace std;
bool T[205],Map[30][205];
int a[6],Left[205];
struct P{
int l,r;
}p[30];
int match(int u){
for(int i=1;i<=a[5];++i){
if(Map[u][i]&&!T[i]){
T[i]=1;
if(!Left[i]||match(Left[i])){
Left[i]=u;
return 1;
}
}
}
return 0;
}
int main()
{
char s[10];
int n,i,j;
map<char,int>mp;
mp['S']=1,mp['M']=2,mp['L']=3,mp['X']=4,mp['T']=5;
while(~scanf("%s",s)){
if(strcmp(s,"ENDOFINPUT")==0) break;
scanf("%d",&n);
memset(Map,0,sizeof(Map));
for(i=1;i<=n;++i){
scanf("%s",s);
p[i].l=mp[s[0]],p[i].r=mp[s[1]];
}
a[0]=0;
for(i=1;i<=5;++i) {scanf("%d",&a[i]); a[i]+=a[i-1];}
for(i=1;i<=n;++i)
for(j=a[p[i].l-1]+1;j<=a[p[i].r];++j) Map[i][j]=1;
int ans=0;
memset(Left,0,sizeof(Left));
for(i=1;i<=n;++i){
memset(T,0,sizeof(T));
ans+=match(i);
}
scanf("%s",s);
if(ans>=n) printf("T-shirts rock!\n");
else puts("I'd rather not wear a shirt anyway...");
}
return 0;
}