题目意思是参赛队员要选择队服,队伍的尺寸有5中,S,M,L,X,T
每个人的衣服的尺寸有个接受范围,在这个范围内的衣服都可以接受。
现在每个尺寸的服装有数量限制,但我们要尽可能要让队员拿到服装。
如果每个人都可以拿到符合要求的服装就输出T-shirts rock!
否则就输出I'd rather not wear a shirt anyway...
输入看上去很复杂,先输入start,再输入参赛人员的个数。
然后输入每个人的服装接受范围,再接着输入每种尺寸服装的数量
接下来输入END
输入ENDINPUT结束输入。
这道题目可以用有点像二分图匹配,但二分图匹配是一对一的,这道题目可以说是一对多
但是我们可以做一点处理,用二分图匹配的匈牙利算法思想。
解题思路,将匈牙利算法中cy变成二维,cy【i】【j】表示第i种服装第j件被选走
Numy【i】的值a表示如果第i种服装被选走,那就是第a件被拿走
这是代码中比较关键的地方。
还有一种想法,我还没实现。
因为这道题目的数据比较小,我们可以把每一件衣服都看成独一无二的衣服,这样就变成了一对多的二分图最大匹配。
#include<iostream> #include<cstdio> #include<cstring> #include<functional> #include<algorithm> #define maxn 35 using namespace std; int maps[maxn][maxn];//邻接矩阵 int cy[maxn][maxn];//点集合Y选中情况 int vis[maxn]; int numy[maxn],limit[maxn];//每种衣服的数量 char s[maxn],a,b; int n; int path(int u)//找增广路 { int i,j; for( i=1;i<=5;i++) { if(maps[u][i]&&!vis[i]) { vis[i]=1; if(numy[i]<limit[i])//其实就是匈牙利算法第二个if语句 { cy[i][numy[i]++]=u; return 1; } else//增广 { for( j=0;j<limit[i];j++) if(path(cy[i][j]))//尝试让这件衣服的主人换件衣服 { cy[i][j]=u; return 1; } } } } return 0; } void MulMatch() { int ans=0; memset(cy,0,sizeof(cy)); memset(numy,0,sizeof(numy)); for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); ans+=path(i); } if(ans==n) printf("T-shirts rock!\n"); else printf("I'd rather not wear a shirt anyway...\n"); } int change(char c) { if(c=='S') return 1; else if(c=='M') return 2; else if(c=='L') return 3; else if(c=='X') return 4; else if(c=='T') return 5; } int main() { int i,j; int st,ed; while(scanf("%s",&s)!=EOF) { if(strcmp(s,"ENDOFINPUT")==0) break; scanf("%d",&n); getchar(); memset(maps,0,sizeof(maps)); for(i=1;i<=n;i++) { scanf("%c%c",&a,&b); getchar(); printf("%c %c\n",a,b); st=change(a); ed=change(b); printf("st=%d ed=%d\n",st,ed); for(j=st;j<=ed;j++) maps[i][j]=1; } for(i=1;i<=5;i++) scanf("%d",&limit[i]); scanf("%s",&s); MulMatch(); } return 0; }