题目大意:
有n件衣服,m个人。
有6种型号衣服,没种衣服件数一样,每种型号n/6件。
每个人可以适合穿两种型号的衣服。
问:能否让所有人都穿上合适的衣服。
解析:
首先图有两个部分,一个是源点与6个点(6种型号)相连,每条边容量为n/6,即每种衣服有几件
第二部分是一个汇点加上m个点(m个人),将所有人的点与汇点相连,边的容量为1,即每个人最后选一件
然后这种型号如果可以时候这个人穿,就连接两点,边的容量加1
有n件衣服,m个人。
有6种型号衣服,没种衣服件数一样,每种型号n/6件。
每个人可以适合穿两种型号的衣服。
问:能否让所有人都穿上合适的衣服。
解析:
首先图有两个部分,一个是源点与6个点(6种型号)相连,每条边容量为n/6,即每种衣服有几件
第二部分是一个汇点加上m个点(m个人),将所有人的点与汇点相连,边的容量为1,即每个人最后选一件
然后这种型号如果可以时候这个人穿,就连接两点,边的容量加1
对这张图用最大流算法,算出最大流,如果等于m说明每个人都满足了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <queue>
#include <map>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 100;
int n,m;
int flow[N][N],cap[N][N];
int p[N],a[N];
map<string,int> hash;
int maxflow(int s,int t) {
int f = 0;
queue<int> que;
memset(flow,0,sizeof(flow));
while(true) {
memset(a,0,sizeof(a));
a[s] = INF;
que.push(s);
while(!que.empty()) {
int u = que.front();
que.pop();
for(int v = 0; v <= t; v++) {
if(!a[v] && cap[u][v] > flow[u][v]) {
p[v] = u;
que.push(v);
a[v] = min(a[u],cap[u][v] - flow[u][v]);
}
}
}
if(a[t] == 0) {
break;
}
for(int u = t; u != s; u = p[u]) {
flow[p[u]][u] += a[t];
flow[u][p[u]] -= a[t];
}
f += a[t];
}
return f;
}
void getHash() {
hash["XS"] = 1;
hash["S"] = 2;
hash["M"] = 3;
hash["L"] = 4;
hash["XL"] = 5;
hash["XXL"] = 6;
}
void init() {
memset(cap,0,sizeof(cap));
int one = n / 6;
for(int v = 1; v <= 6; v++) {
cap[0][v] = one;
}
char str1[N],str2[N];
for(int v = 1; v <= m; v++) {
scanf("%s%s",str1,str2);
int u1 = hash[str1], u2 = hash[str2];
cap[u1][v+6] = 1;
cap[u2][v+6] = 1;
}
for(int u = 1; u <= m; u++) {
cap[u+6][6+m+1] = 1;
}
}
int main() {
getHash();
int T;
scanf("%d",&T);
while(T--) {
scanf("%d%d",&n,&m);
init();
int ans = maxflow(0,6+m+1);
if(ans == m) {
printf("YES\n");
}else {
printf("NO\n");
}
}
return 0;
}