题意:就是n个人,每个人只能从几件适合自己大小的衣服中选一件,衣服型号共有5种,每种型号的衣服数量有限,问是否存在一种分配方法,使得每个人都能选到自己合适的衣服。
应该说此题建图很简单,但鉴于小弟建图水平太渣,还处于并将长期处于“低级阶段”,所以这题我建图后,发现我建图方法有点多此一举的感觉。。。。
较好的建图方法:添加一个源点s‘和汇点t’,源点与每个人连一条边容量为1,每个人与适合他大小的衣服连成一条边容量为1,每种大小的衣服与汇点t‘连成一条边容量为其对应的数量
我的建图:我的建图,是把每种型号的衣服拆点后,各自连边容量为INF
以下图是在题目中的第一个数据基础上建立的
一种较好的建图方法:
附上代码:
#include<iostream>
using namespace std;
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<algorithm>
#define MAXM 10000
#define MAXN 1000
#define oo 0x7fffffff
inline int num(char ch)
{
if (ch=='S') return 1;
if (ch=='M') return 2;
if (ch=='L') return 3;
if (ch=='X') return 4;
if (ch=='T') return 5;
}
struct Dinic
{
struct node
{
int x,y,c,next;
}line[MAXM];
int Lnum,_next[MAXN],dis[MAXN];
void initial(int n)
{
for (int i=0;i<=n;i++) _next[i]=-1;
Lnum=-1;
}
void addline(int x,int y,int c)
{
line[++Lnum].next=_next[x],_next[x]=Lnum;
line[Lnum].x=x,line[Lnum].y=y,line[Lnum].c=c;
line[++Lnum].next=_next[y],_next[y]=Lnum;
line[Lnum].x=y,line[Lnum].y=x,line[Lnum].c=0;
}
bool BFS(int s,int e)
{
queue<int> Q;
while (!Q.empty()) Q.pop();
memset(dis,0,sizeof(dis));
dis[s]=1;
Q.push(s);
while (!Q.empty())
{
int h,k;
h=Q.front(),Q.pop();
if (h==e) return dis[e];
for (k=_next[h];k!=-1;k=line[k].next)
if (line[k].c && !dis[line[k].y])
dis[line[k].y]=dis[h]+1,Q.push(line[k].y);
}
return false;
}
int dfs(int x,int flow,int e)
{
if (x==e) return flow;
int temp,cost=0;
for (int k=_next[x];k!=-1;k=line[k].next)
if (line[k].c && dis[line[k].y]==dis[x]+1)
{
temp=dfs(line[k].y,min(flow-cost,line[k].c),e);
if (temp)
{
line[k].c-=temp,line[k^1].c+=temp;
cost+=temp;
if (flow==cost) return cost;
}else dis[line[k].y]=-1;
}
return cost;
}
int MaxFlow(int s,int e)
{
int MaxFlow=0;
while (BFS(s,e))
MaxFlow+=dfs(s,oo,e);
return MaxFlow;
}
}T;
int main()
{
string s;
int i;
while (cin >> s,s!="ENDOFINPUT")
{
int n;
cin >> n;
int N=n+6;
T.initial(N);
for (i=0;i<n;++i) T.addline(0,i+1,1);
for (i=0;i<n;++i)
{
string str;
cin >> str;
int x1=num(str[0]),x2=num(str[1]);
for (int j=x1;j<=x2;++j)
T.addline(i+1,n+j,1);
}
for (i=1;i<=5;++i)
{
int x;
cin >> x;
if (x>0)
T.addline(n+i,N,x);
}
string s1;
if (T.MaxFlow(0,N)==n) cout << "T-shirts rock!" <<endl;
else cout << "I'd rather not wear a shirt anyway..." << endl;
cin >> s1;
}
return 0;
}