题意:有N件T恤,N是6的倍数,因为有6种型号,每种件数相同,有M个人,每个人有两种型号的T恤适合他,每个人可以挑其中的一种,问能否所有的人都能分配到T恤。
解析:典型的二分图匹配,每N/6为同种T恤,对于单个人,将他与它适合的两种T恤的所有标号连边,最后计算最大匹配,如果小于M,则不可行,否则可行。
代码如下:
#include<cstdio>
#include<cstring>
#include<string> #include<algorithm> #include<set> #include<map> #include<queue> #include<vector> #include<iterator> #include<utility> #include<sstream> #include<iostream> #include<cmath> #include<stack> using namespace std; const int INF=1000000007; const double eps=0.00000001; vector<int> G[40]; int le[40],ri[40]; int N,M; string type[]={"S","M","L","XS","XL","XXL"}; //6种型号的T恤 bool vis[40]; bool dfs(int cur) //二分图匹配模板 { if(vis[cur]) return false; vis[cur]=true; for(int i=0;i<G[cur].size();i++) { int to=G[cur][i]; if(ri[to]==-1||dfs(ri[to])) { le[cur]=to; ri[to]=cur; return true; } } return false; } bool Match() { int ret=0; memset(le,-1,sizeof(le)); memset(ri,-1,sizeof(ri)); for(int i=1;i<=N;i++) { memset(vis,false,sizeof(vis)); if(dfs(i)) ret++; //如果能匹配,则加1 if(ret==M) return true; //达到M,直接返回真 } return false; } int main() { int T; cin>>T; map<string,int> ma; for(int i=0;i<6;i++) ma[type[i]]=i; //将T恤型号映射成编号 while(T--) { cin>>N>>M; for(int i=1;i<=N;i++) G[i].clear();