POJ 2584 T-Shirt Gumbo 构图 最大流

题意:acmer比赛穿的T-shirt 有 S M L X T五种型号,每个人穿的型号介于给出的两字母之间,五种 T-shirt 每种都有一定的数量,

问是否每个人都可以得到自己需要的型号

 

这个题。。。不评价。。。开始构图构错了,本想增加一个源点m,增加一个汇点,中间只要 T-shirt的5个点,如果有队员需要某种

 

 

T-shirt,该点与源点的连线就+1。某种T-shirt数量有多少,就把该点与汇点连线,权值为该T-shirt的数量,结果WA,好好考虑也是,

 

 

不画出错误的图了。 正确的思路,把人和T-shirt 都看成点,人和源点连线,权值为1,该队员再和需要的T-shirt 连线,权值为1,然后

 

 

T-shirt再与汇点连线,权值为数量。。。

 

 

代码:

 

       

//虽然点不多,由于构图原因,不能用矩阵map
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<queue>
#define inf 1<<30
#define mMAX 300
#define nMAX 30
#define Min(a,b)a<b?a:b
using namespace std;
int level[nMAX],head[nMAX];
int n,t,s_edge;
int a[100];
struct Edge
{
    int to,w,next;
} edge[mMAX];

void addedge(int u,int v,int W)
{
    s_edge++;
    edge[s_edge].to=v;
    edge[s_edge].w=W;
    edge[s_edge].next=head[u];
    head[u]=s_edge;

    s_edge++;
    edge[s_edge].to=u;
    edge[s_edge].w=0;
    edge[s_edge].next=head[v];
    head[v]=s_edge;
    return ;
}

int dfs(int x,int cap)
{
    if(x==t)return cap;
    int temp=cap;
    for(int e=head[x];e;e=edge[e].next)
    {
        int To=edge[e].to;
        if(level[To]==level[x]+1&&temp>0&&edge[e].w>0)
        {
            int tt=dfs(To,Min(temp,edge[e].w));
            edge[e].w-=tt;
            edge[e^1].w+=tt;
            temp-=tt;
        }
    }
    return cap-temp;
}

bool bfs()
{
    queue<int>qu;
    memset(level,-1,sizeof(level));
    level[0]=0;
    qu.push(0);
    while(!qu.empty())
    {
        int tt=qu.front();
        qu.pop();
        for(int e=head[tt];e;e=edge[e].next)
        {
            int To=edge[e].to;
            if(level[To]==-1&&edge[e].w>0)
            {
                level[To]=level[tt]+1;
                qu.push(To);
            }
        }
    }
    if(level[t]!=-1)return 1;
    return 0;
}

int dinic()
{
    int SUM=0;
    while(bfs())
    {
        SUM+=dfs(0,inf);
    }
    return SUM;
}

void init()//由于惯性,开始写的 ch2[0]-64,意思就是从A开始,太机械了!         
{
    a['S']=1;
    a['M']=2;
    a['L']=3;
    a['X']=4;
    a['T']=5;
    return ;
}

int main()
{
    init();
    char ch1[20],ch2[3];
    int i,j;
    while(~scanf("%s",ch1))
    {
        if(!strcmp(ch1,"ENDOFINPUT"))
          break;

        memset(head,0,sizeof(head));
        s_edge=1;

        scanf("%d",&n);
        t=n+6;
        for(i=1;i<=n;i++)
        {
            addedge(0,i,1);
            scanf("%s",ch2);
            int m1=ch2[0],m2=ch2[1];
            for(j=a[m1];j<=a[m2];j++)
               addedge(i,j+n,1);
        }
        int num=0;
        for(i=1;i<=5;i++)
        {
            scanf("%d",&j);
            addedge(i+n,t,j);
            num+=j;//开始写的num++,晕死,不来动脑子的

        }
        scanf("%s",ch1);
        if(num<n)//剪枝
        printf("I'd rather not wear a shirt anyway...\n");

        else
        {
          num=dinic();
          if(num<n)
          printf("I'd rather not wear a shirt anyway...\n");
          else printf("T-shirts rock!\n");
        }
    }
    return 0;
}

  

  

posted @ 2012-02-19 00:33  快乐.  阅读(186)  评论(0)    收藏  举报