最大流:0为源点,m+7为汇点,源点到每种志愿服的容量是n/6,志愿服和志愿者之间的容量是1,志愿者和汇点之间的容量是1,然后其余源点到汇点的最大流F,若F==m则输出YES,否则就是NO..
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<queue> const int inf=89999999; using namespace std; const int N=100; string g[10]={"\0","XXL","XL","L","M","S","XS"}; int G[100][100]; int a[100]; int flow[100][100]; int p[100]; int n,m,F,V; void EK_() { queue<int>q; memset(flow,0,sizeof(flow)); for(;;) { memset(a,0,sizeof(a)); a[0]=inf; q.push(0); while(!q.empty()) { int u=q.front(); q.pop(); for(int v=0;v<=V;v++) { if(!a[v]&&G[u][v]>flow[u][v]) { p[v]=u; q.push(v); a[v]=a[u]; if(a[v]>G[u][v]-flow[u][v]) a[v]=G[u][v]-flow[u][v]; } } } if(a[V]==0) break; for(int u=V;u!=0;u=p[u]) { flow[p[u]][u]+=a[V]; flow[u][p[u]]-=a[V]; } F+=a[V]; } } int main() { int T; scanf("%d",&T); while(T--) { memset(G,0,sizeof(G)); scanf("%d%d",&n,&m); V=m+7; string s1,s2; for(int i=1;i<=6;i++) G[0][i]=n/6; for(int i=1;i<=m;i++) { cin>>s1>>s2; int a1,a2; for(a1=1;g[a1]!=s1;a1++); for(a2=1;g[a2]!=s2;a2++); G[a1][i+6]=1; G[a2][i+6]=1; G[i+6][V]=1; } F=0; EK_(); if(F==m) cout<<"YES\n"; else cout<<"NO\n"; } return 0; }