题意:
有xn个参赛者,给出每个参赛者所需要的衣服的尺码的大小范围,在该尺码范围内的衣服该选手可以接受,给出这5种型号衣服各自的数量,问是否存在一种分配方案使得每个选手都能够拿到自己尺码范围内的衣服.
思路:最大流 建立超级源点src 与5种衣服相连 边权为衣服的数量 超级汇点与xn个人相连 边权为1 然后每个人与自己相应的尺码间也建立一条边,边权为1 求最大流 等于 xn 就输出 T-shirts rock! 反之 I'd rather not wear a shirt anyway...
下面代码很怪,用codeblocks 运行不出来正确答案 用vc就OK 啥原因不明。。。。 = =||
//388K
0MS
#include <stdio.h>
#include <string.h>
#define VM 30
#define EM 300
const int inf = 0x3f3f3f3f;
struct E
{
int to,cap,nxt;
} edge[EM];
int head[VM],dep[VM],cur[VM],pre[VM],gap[VM];
int e,N,x,src,des;
void addedge (int cu,int cv,int cw)
{
edge[e].to = cv;
edge[e].cap = cw;
edge[e].nxt = head[cu];
head[cu] = e ++;
edge[e].to = cu;
edge[e].cap = 0;
edge[e].nxt = head[cv];
head[cv] = e ++;
}
void Init() 建图
{
int i,x1,x2,num;
char s2[5];
scanf ("%d",&x);
//x是人数
src = 0,des = x + 6;
N = des + 1;
//总的点数 两超级点 + xn个人+ 5种型号衣服
for (i = 1;i <= x;i ++)
{
scanf ("%s",s2);
if (s2[0] == 'S')
x1 = x + 1;
if (s2[0] == 'M')
x1 = x + 2;
if (s2[0] == 'L')
x1 = x + 3;
if (s2[0] == 'X')
x1 = x + 4;
if (s2[0] == 'T')
x1 = x + 5;
if (s2[1] == 'S')
x2 = x + 1;
if (s2[1] == 'M')
x2 = x + 2;
if (s2[1] == 'L')
x2 = x + 3;
if (s2[1] == 'X')
x2 = x + 4;
if (s2[1] == 'T')
x2 = x + 5;
for (int j = x1; j <= x2;j ++) //相应尺码的衣服与相应的人相边
addedge(j,i,1);
addedge (i,des,1);
//人与超级汇点相连
}
for (i = 1;i <= 5;i ++)
//5种衣服与超级源点相连
{
scanf ("%d",&num);
addedge(src,x+i,num);
}
scanf ("%s",s2);
//接收"END"
}
int min (int a,int b)
{
return a > b ? b : a;
}
int Sap ()
//sap算法 没什么好说的
{
memset (dep,0,sizeof(dep));
memset (gap,0,sizeof(gap));
memcpy (cur,head,sizeof(head));
int u = pre[src] = src;
int res = 0,aug = inf;
gap[0] = N;
while (dep[src] < N)
{
loop:
for (int &i = cur[u];i != -1;i = edge[i].nxt)
{
int v = edge[i].to;
if (edge[i].cap && dep[u] == dep[v] + 1)
{
aug = min (aug,edge[i].cap);
pre[v] = u;
u = v;
if (v == des)
{
res += aug;
for (u = pre[u];v != src;v = u,u = pre[u])
{
edge[cur[u]].cap -= aug;
edge[cur[u]^1].cap += aug;
}
aug = inf;
}
goto loop;
}
}
int mindep = N;
for (int j = head[u];j != -1;j = edge[j].nxt)
{
int v = edge[j].to;
if (edge[j].cap && mindep > dep[v])
{
cur[u] = j;
mindep = dep[v];
}
}
if ((--gap[dep[u]]) == 0)
break;
dep[u] = mindep + 1;
gap[dep[u]] ++;
u = pre[u];
}
return res;
}
int main ()
{
//freopen ("in.txt","r",stdin);
char s1[15];
while (scanf ("%s",s1))
{
memset (head,-1,sizeof(head));
e = 0;
if (strcmp(s1,"ENDOFINPUT") == 0)
break;
Init();
if (Sap() != x)
printf ("I'd rather not wear a shirt anyway...\n");
else
printf ("T-shirts rock!\n");
}
return 0;
}
思路:最大流 建立超级源点src 与5种衣服相连 边权为衣服的数量 超级汇点与xn个人相连 边权为1 然后每个人与自己相应的尺码间也建立一条边,边权为1 求最大流 等于 xn 就输出
下面代码很怪,用codeblocks 运行不出来正确答案 用vc就OK 啥原因不明。。。。 = =||
//388K
#include <stdio.h>
#include <string.h>
#define VM 30
#define EM 300
const int inf = 0x3f3f3f3f;
struct E
{
} edge[EM];
int head[VM],dep[VM],cur[VM],pre[VM],gap[VM];
int e,N,x,src,des;
void addedge (int cu,int cv,int cw)
{
}
void Init() 建图
{
}
int min (int a,int b)
{
}
int Sap ()
{
}
int main ()
{
}