算是最大流基础题了吧。
构图:多出一个源点start,一个汇点final
源点到5个衣服的边权值是每个衣服的数量数。
然后每个衣服到匹配的人的边权值都是1,然后每个人到汇点的边权值都是1.
这样最大流一下,其实就是用最大流求最大匹配。
#include<iostream>
#include<queue>
using namespace std;
const int N=200;
const int M=2000;
char range[N][2];
bool visit[N];
int pre[N];
int k=1;
int start;
int final;
int n;
char getcha[6]={'0','S','M','L','X','T'};
int getin(char a)
{
switch(a)
{
case 'S':return 1;
case 'M':return 2;
case 'L':return 3;
case 'X':return 4;
case 'T':return 5;
}
}
struct node
{
int v,w,next,re;
}edge[M];
int edgehead[N];
void addedge(int a ,int b,int w)
{
edge[k].v=b;
edge[k].w=w;
edge[k].next=edgehead[a];
edge[k].re=k+1;
edgehead[a]=k++;
edge[k].v=a;
edge[k].w=0;
edge[k].next=edgehead[b];
edge[k].re=k-1;
edgehead[b]=k++;
}
bool bfs()
{
memset(visit,0,sizeof(visit));
memset(pre,0,sizeof(pre));
queue<int> que;
que.push(start);
visit[start]=true;
while(!que.empty())
{
int now=que.front();
que.pop();
for(int i=edgehead[now];i!=0;i=edge[i].next)
{
if(edge[i].w>0&&!visit[edge[i].v])
{
visit[edge[i].v]=true;
que.push(edge[i].v);
pre[edge[i].v]=i;
if(edge[i].v==final)
return true;
}
}
}
return false;
}
void solve()
{
int ans=0;
while(bfs())
{
int now=final;
while(now!=start)
{
int t=pre[now];
edge[t].w-=1;
edge[edge[t].re].w+=1;
now=edge[edge[t].re].v;
}
ans++;
}
if(ans<n)
printf("I'd rather not wear a shirt anyway...\n");
else
printf("T-shirts rock!\n");
}
int main()
{
char str[20];
while(scanf("%s %d",str,&n),str[0]=='S')
{
k=1;
start=n+6;
final=n+7;
memset(edgehead,0,sizeof(edgehead));
memset(edge,0,sizeof(edge));
memset(pre,0,sizeof(pre));
for(int i=1;i<=n;i++)
{
scanf("%s",range[i]);
for(int j=getin(range[i][0]);j<=getin(range[i][1]);j++)
{
addedge(j,i+5,1);
}
}
int tmp;
for(int i=1;i<=5;i++)
{
scanf("%d",&tmp);
addedge(n+5+1,i,tmp);
}
for(int i=1;i<=n;i++)
{
addedge(5+i,n+5+2,1);
}
solve();
scanf("%s",str);
}
return 0;
}