一开始就想到网络流。。后来一想暴力能不能过。自己写的T了。看了别人有暴力过的。
暴力的思路就是6进制数字表示给予的衣服的数量。然后每个人的需求表示成01 的6位串然后爆搜。
网络流就建一个源一个汇 然后针对输入 i - i + 6 边权为N/6; 然后M个人由衣服连M个人边权为1。与源直接相连的点就INF求最大流值判断即可。
别人的建图更简单一些。不需要设置INF;思路一样
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <climits> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define LL long long #define PI 3.1415926535897932626 using namespace std; int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);} int src,tag; int N,M; const int INF = 0x3f3f3f3f ; char size[10][20] = {"xxa","XXL","XL","L","M","S","XS"}; int d[100],cap[100][100]; bool inq[100]; int flow[100][100]; int p[100]; void read() { scanf("%d%d",&N,&M); N /= 6; memset(cap,0,sizeof(cap)); for (int i = 1; i <= 6; i++) { cap[0][i] = INF; cap[i][i + 6] = N; } for (int j = 1; j <= M; j++) { char a[8],b[8]; scanf("%s%s",a,b); int s1 = -1, s2; for (int i = 1; i <= 6; i++) { if (strcmp(size[i],a) == 0) s1 = i; if (strcmp(size[i],b) == 0) s2 = i; } //printf("%d %d\n",s1,s2); cap[s1 + 6][12 + j] = 1; cap[s2 + 6][12 + j] = 1; cap[12 + j][12 + M + 1] = 1; } src = 0; tag = 12 + M + 1; } int Edmons_karp() { queue<int>q; int a[100]; while (!q.empty()) q.pop(); memset(flow,0,sizeof(flow)); int ans = 0; while (true) { memset(a,0,sizeof(a)); a[src] = INF; q.push(src); while(!q.empty()) { int u = q.front(); q.pop(); for (int v = 1; v <= tag; v++) if (!a[v] && cap[u][v] > flow[u][v]) { p[v] = u; q.push(v); a[v] = min(a[u],cap[u][v] - flow[u][v]); } } if (a[tag] == 0) break; for (int u = tag; u != src; u = p[u]) { flow[p[u]][u] += a[tag]; flow[u][p[u]] -= a[tag]; } ans += a[tag]; } return ans; } int main() { //freopen("sample.txt","r",stdin); int T; scanf("%d",&T); while (T--) { read(); int ans = Edmons_karp(); //printf("%d\n",ans); if (ans >= M) printf("YES\n"); else printf("NO\n"); } return 0; }
TLE 的代码也贴一下吧
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <climits> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define LL long long #define PI 3.1415926535897932626 using namespace std; int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);} int st[32]; int N,M; bool found; char size[10][20] = {"XXL","XL","L","M","S","XS"}; int res; void read() { res = 0; scanf("%d%d",&N,&M); N /= 6; char tmp[10]; for (int i = 0; i < 6 ; i++) tmp[i] = N + '0'; tmp[6] = '\0'; sscanf(tmp,"%d",&res); memset(st,0,sizeof(st)); for (int i = 1; i <= M; i++) { char a[6],b[6]; scanf("%s%s",a,b); int j; for (j = 0; j < 6; j++) if (strcmp(a,size[j]) == 0) break; st[i] |= 1 << j; for (j = 0; j < 6; j++) if (strcmp(b,size[j]) == 0) break; st[i] |= 1 << j; } } void calcu(int cur, int sta, int cnt) { if (found) return ; if (cnt >= M) { found = true; return ; } int temp = sta; bool change = false; char str[20]; for (int i = cur; i <= M; i++) { int a = -1,b = -1; for (int j = 0; j < 6; j++) { if (st[i] & (1 << j)) { if (a == -1) { a = j; } else b = j; } } sprintf(str,"%d",temp); if (str[a] - '0' > 0) { change = true; str[a]--; sscanf(str,"%d",&temp); calcu(cur + 1, temp, cnt + 1); str[a]++; } temp = sta; if (str[b] - '0' > 0) { change = true; str[b]--; sscanf(str,"%d",&temp); calcu(cur + 1, temp, cnt + 1); str[b]++; } if (!change) return ; } } int main() { //freopen("sample.txt","r",stdin); int T; scanf("%d",&T); while (T--) { found = false; read(); calcu(1,res,0); if (found) printf("YES\n"); else printf("NO\n"); } return 0; }