Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 3164 | Accepted: 1481 |
Description
Input
Output
Sample Input
START 1
ST
0 0 1 0 0
END
START 2
SS TT
0 0 1 0 0
END
START 4
SM ML LX XT
0 1 1 1 0
END
ENDOFINPUT
Sample Output
T-shirts rock!
I'd rather not wear a shirt anyway...
I'd rather not wear a shirt anyway...
Source
题目大意:
有n个队员,每个队员给出两个字母,表示其当前队员能够接受的衣服的大小区间,衣服大小一共有五种,给你每一种衣服的数目,问你是否所有队员能够拿到其能够接受的衣服大小。
思路:
1、经典的多重匹配问题,用多重匹配匈牙利算法也可以,用最大流也可以,这里给出最大流的思路。
2、建图如下:
①建立源点S,连入各个队员,其权值设定为1,表示每个队员需要拿一件衣服。
②建立汇点T,将各个衣服节点连入汇点T,其权值设定为衣服的数量,表示每种衣服最多能够拿多少次。
③将每个队员连入各个可以接受的衣服大小节点,其权值设定为1.
3、建好图之后跑一遍最大流,判断maxflow是否等于n,如果等于n,那么表示可行,否则表示不可行。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
using namespace std;
struct node
{
int from;
int to;
int w;
int next;
}e[151511];
//SMLXT
int head[5000];
int cur[5000];
int divv[5000];
char a[1500];
int n,ss,cont,tt;
void add(int from,int to,int w)
{
e[cont].to=to;
e[cont].w=w;
e[cont].next=head[from];
head[from]=cont++;
}
int makedivv()
{
queue<int >s;
s.push(ss);
memset(divv,0,sizeof(divv));
divv[ss]=1;
while(!s.empty())
{
int u=s.front();
if(u==tt)return 1;
s.pop();
for(int i=head[u];i!=-1;i=e[i].next)
{
int w=e[i].w;
int v=e[i].to;
if(w&&divv[v]==0)
{
divv[v]=divv[u]+1;
s.push(v);
}
}
}
return 0;
}
int Dfs(int u,int maxflow,int tt)
{
if(u==tt)return maxflow;
int ret=0;
for(int &i=cur[u];i!=-1;i=e[i].next)
{
int v=e[i].to;
int w=e[i].w;
if(w&&divv[v]==divv[u]+1)
{
int f=Dfs(v,min(maxflow-ret,w),tt);
e[i].w-=f;
e[i^1].w+=f;
ret+=f;
if(ret==maxflow)return ret;
}
}
return ret;
}
void Dinic()
{
int ans=0;
while(makedivv()==1)
{
memcpy(cur,head,sizeof(head));
ans+=Dfs(ss,0x3f3f3f3f,tt);
}
if(ans==n)printf("T-shirts rock!\n");
else printf("I'd rather not wear a shirt anyway...\n");
}
int main()
{
while(~scanf("%s",a))
{
cont=0;
memset(head,-1,sizeof(head));
if(strcmp(a,"ENDOFINPUT")==0)break;
scanf("%d",&n);
ss=n+6;
tt=ss+1;
for(int i=1;i<=n;i++)
{
int l=0;
int r=0;
scanf("%s",&a);
if(a[0]=='S')l=n+1;
if(a[0]=='M')l=n+2;
if(a[0]=='L')l=n+3;
if(a[0]=='X')l=n+4;
if(a[0]=='T')l=n+5;
if(a[1]=='S')r=n+1;
if(a[1]=='M')r=n+2;
if(a[1]=='L')r=n+3;
if(a[1]=='X')r=n+4;
if(a[1]=='T')r=n+5;
for(int j=l;j<=r;j++)
{
add(i,j,1);
add(j,i,0);
}
}
for(int i=1;i<=n;i++)
{
add(ss,i,1);
add(i,ss,0);
}
for(int i=1;i<=5;i++)
{
int tmp;
scanf("%d",&tmp);
add(i+n,tt,tmp);
add(tt,i+n,0);
}
scanf("%s",a);
Dinic();
}
return 0;
}