题意:有n个同学要求订购衣服,每个同学可以接收的衣服型号已知(一个人一件衣服),现在每个型号的衣服数量已知,问能不能满足同学的要求?
思路:可行性问题,此题方法很多,多重二分匹配、BFS等,我偷懒用了最大流,BS我吧.......还是说下建图过程吧,增加源汇点s,t,每个同学与其所接受的型号连一条1的边,s与同学连INF边,型号和t连val (val 是此型号的数量),然后求最大流......
#include < iostream >
#include < cstdio >
#include < algorithm >
#include < memory.h >
#include < cmath >
#include < bitset >
#include < queue >
#include < vector >
using namespace std;
const int BORDER = ( 1 << 20 ) - 1 ;
const int MAXSIZE = 37 ;
const int MAXN = 200 ;
const int INF = INT_MAX;
#define CLR(x,y) memset(x,y,sizeof(x))
#define ADD(x) x=((x+1)&BORDER)
#define IN(x) scanf("%d",&x)
#define OUT(x) printf("%d\n",x)
#define MIN(m,v) (m)<(v)?(m):(v)
#define MAX(m,v) (m)>(v)?(m):(v)
#define ABS(x) ((x)>0?(x):-(x))
int index,nv,n,m,k,s,t;
int ans;
int net[MAXN];
int need[ 30 ];
int have[ 10 ];
struct Edge{
int next,pair;
int v,cap,flow;
}edge[MAXN * MAXN];
int init()
{
CLR(net, - 1 );
CLR(have, 0 );
CLR(need, 0 );
index = 0 ;
need[ ' S ' ] = 1 ;
need[ ' M ' ] = 2 ;
need[ ' L ' ] = 3 ;
need[ ' X ' ] = 4 ;
need[ ' T ' ] = 5 ;
return 0 ;
}
void add_edge( const int & u, const int & v, const int & val)
{
edge[index].next = net[u];
net[u] = index;
edge[index].v = v;
edge[index].cap = val;
edge[index].flow = 0 ;
edge[index].pair = index + 1 ;
++ index;
edge[index].next = net[v];
net[v] = index;
edge[index].v = u;
edge[index].cap = 0 ;
edge[index].flow = 0 ;
edge[index].pair = index - 1 ;
++ index;
}
int input()
{
string op;
int i,j,start,end;
cin >> op;
if (op.length() > 6 )
return 1 ;
cin >> n;
s = n + 5 + 1 ;
t = n + 5 + 2 ;
nv = t;
for (i = 1 ; i <= n; ++ i)
{
cin >> op;
for (j = need[op[ 0 ]]; j <= need[op[ 1 ]]; ++ j)
add_edge(i,n + j, 1 );
add_edge(s,i, 1 );
}
for (i = 1 ; i <= 5 ; ++ i)
{
cin >> j;
add_edge(i + n,t,j);
}
cin >> op;
return 0 ;
}
int ISAP()
{
long numb[MAXN],dist[MAXN],curedge[MAXN],pre[MAXN];
long cur_flow,max_flow,u,tmp,neck,i;
memset(dist, 0 , sizeof (dist));
memset(numb, 0 , sizeof (numb));
for (i = 1 ; i <= nv ; ++ i)
curedge[i] = net[i];
numb[nv] = nv;
max_flow = 0 ;
u = s;
while (dist[s] < nv)
{
/* first , check if has augmemt flow */
if (u == t)
{
cur_flow = INF;
for (i = s; i != t;i = edge[curedge[i]].v)
{
if (cur_flow > edge[curedge[i]].cap)
{
neck = i;
cur_flow = edge[curedge[i]].cap;
}
}
for (i = s; i != t; i = edge[curedge[i]].v)
{
tmp = curedge[i];
edge[tmp].cap -= cur_flow;
edge[tmp].flow += cur_flow;
tmp = edge[tmp].pair;
edge[tmp].cap += cur_flow;
edge[tmp].flow -= cur_flow;
}
max_flow += cur_flow;
u = s;
}
/* if .... else ... */
for (i = curedge[u]; i != - 1 ; i = edge[i].next)
if (edge[i].cap > 0 && dist[u] == dist[edge[i].v] + 1 )
break ;
if (i != - 1 )
{
curedge[u] = i;
pre[edge[i].v] = u;
u = edge[i].v;
} else {
if ( 0 == -- numb[dist[u]]) break ;
curedge[u] = net[u];
for (tmp = nv,i = net[u]; i != - 1 ; i = edge[i].next)
if (edge[i].cap > 0 )
tmp = tmp < dist[edge[i].v] ? tmp:dist[edge[i].v];
dist[u] = tmp + 1 ;
++ numb[dist[u]];
if (u != s) u = pre[u];
}
}
return max_flow;
}
int work()
{
int i,j,tmp;
ans = ISAP();
if (ans == n)
printf( " T-shirts rock!\n " );
else
printf( " I'd rather not wear a shirt anyway...\n " );
return 0 ;
}
int main()
{
int res;
while ( true )
{
init();
res = input();
if (res)
break ;
work();
}
return 0 ;
}