poj 2584 T-Shirt Gumbo(最大流 s…

题意: 有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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值