POJ 2584 TShirt Gumbo(最大流)

题意:有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;
}

原文地址:https://www.cnblogs.com/lvpengms/p/1797541.html