注意细节细节!!!
用网络流来做一定很轻松-.-
将多重匹配变为最大匹配,数据较小,可以过....
#include<iostream>
#include<cstdio>
using namespace std;
struct Edge
{
int v,next;
}E[111111];
struct SEG
{
int s,e;
};
int ptr[222],match[222],Edgenum;
bool vis[222];
int change( char c )
{
if( c=='S' ) return 0;
if( c=='M' ) return 1;
if( c=='L' ) return 2;
if( c=='X' ) return 3;
if( c=='T' ) return 4;
}
void addEdge( int u,int v )
{
E[Edgenum].v=v;
E[Edgenum].next=ptr[u];
ptr[u]=Edgenum++;
}
bool Match( int cur )
{
for( int i=ptr[cur];i!=-1;i=E[i].next )
{
if( !vis[E[i].v] )
{
vis[E[i].v]=true;
if( match[E[i].v]==-1 || Match(match[E[i].v]) )
{
match[E[i].v]=cur;
return true;
}
}
}
return false;
}
int main()
{
//freopen( "test.in","r",stdin );
//freopen( "test.out","w",stdout );
char str[222];
while( scanf("%s",&str)!=EOF )
{
memset( match,-1,sizeof(match) );
memset( ptr,-1,sizeof(ptr) );
Edgenum=0;
if( strcmp(str,"ENDOFINPUT")==0 )
break;
int N;
SEG seg[111];
scanf( "%d",&N );
for( int i=0;i<N;i++ )
{
scanf( "%s",&str );
seg[i].s=change(str[0]);
seg[i].e=change(str[strlen(str)-1]);
}
int num[5];
for( int i=0;i<5;i++ )
{
scanf( "%d",&num[i] );
if( i ) num[i]+=num[i-1];
}
scanf( "%s",&str );
for( int i=0;i<N;i++ )//每个人
{
for( int j=seg[i].s;j<=seg[i].e;j++ )//尺寸范围
{
int k=(j==0)?0:num[j-1];
for( ;k<num[j];k++ )
addEdge(i,k+N);
}
}
int ans=0;
for( int i=0;i<N;i++ )
{
memset( vis,0,sizeof(vis) );
if( Match(i) )
ans++;
}
printf( "%s\n",ans==N?"T-shirts rock!":"I'd rather not wear a shirt anyway..." );
}
return 0;
}