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;
}

浙公网安备 33010602011771号