poj 2584 T-Shirt Gumbo 网络流

题目链接

有5种T-shirt, n个人, 每个人可以接受某些种T-shirt, 每种T-shirt的数量已知, 问每个人能否都穿上自己能接受的T-shirt。

源点向每种T-shirt连边, 权值为个数。 将人拆成两个点u和u', T-shirt向u连边, 权值为1, u向u'连边, 权值为1, u'向汇点连边, 权值为inf。 跑一遍最大流, 看结果是否等于n就可以了。

很简单的题写了好久orz....代码能力太差了。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define mem(a) memset(a, 0, sizeof(a))
  4 #define mem1(a) memset(a, -1, sizeof(a))
  5 const int inf = 1061109567;
  6 const int maxn = 1e4+5;
  7 int head[maxn*4], s, t, num, q[maxn*10], dis[maxn];
  8 struct node
  9 {
 10     int to, nextt, c;
 11 }e[maxn*4];
 12 void init() {
 13     mem1(head);
 14     num = 0;
 15 }
 16 void add(int u, int v, int c) {
 17     e[num].to = v; e[num].nextt = head[u]; e[num].c = c; head[u] = num++;
 18     e[num].to = u; e[num].nextt = head[v]; e[num].c = 0; head[v] = num++;
 19 }
 20 int bfs() {
 21     int u, v, st = 0, ed = 0;
 22     mem(dis);
 23     dis[s] = 1;
 24     q[ed++] = s;
 25     while(st<ed) {
 26         u = q[st++];
 27         for(int i = head[u]; ~i; i = e[i].nextt) {
 28             v = e[i].to;
 29             if(e[i].c&&!dis[v]) {
 30                 dis[v] = dis[u]+1;
 31                 if(v == t)
 32                     return 1;
 33                 q[ed++] = v;
 34             }
 35         }
 36     }
 37     return 0;
 38 }
 39 int dfs(int u, int limit) {
 40     if(u == t)
 41         return limit;
 42     int cost = 0;
 43     for(int i = head[u]; ~i; i = e[i].nextt) {
 44         int v = e[i].to;
 45         if(e[i].c&&dis[u] == dis[v]-1) {
 46             int tmp = dfs(v, min(limit-cost, e[i].c));
 47             if(tmp>0) {
 48                 e[i].c -= tmp;
 49                 e[i^1].c += tmp;
 50                 cost += tmp;
 51                 if(cost == limit)
 52                     break;
 53             } else {
 54                 dis[v] = -1;
 55             }
 56         }
 57     }
 58     return cost;
 59 }
 60 int dinic() {
 61     int ans = 0;
 62     while(bfs()) {
 63         ans += dfs(s, inf);
 64     }
 65     return ans;
 66 }
 67 map <char, int> m;
 68 int val[6];
 69 char c[50][3];
 70 int main()
 71 {
 72     m['S'] = 1, m['M'] = 2, m['L'] = 3, m['X'] = 4, m['T'] = 5;
 73     string str;
 74     int n;
 75     while(cin>>str) {
 76         init();
 77         if(str == "ENDOFINPUT")
 78             break;
 79         scanf("%d", &n);
 80         s = 0, t = 2*n+5+1;
 81         for(int i = 1; i<=n; i++) {
 82             scanf("%s", c[i]);
 83         }
 84         for(int i = 1; i<=5; i++) {
 85             scanf("%d", &val[i]);
 86         }
 87         for(int i = 1; i<=5; i++) {
 88             add(s, i, val[i]);
 89         }
 90         for(int i = 1; i<=n; i++) {
 91             if(c[i][0] == c[i][1]) {
 92                 add(m[c[i][0]], i+5, 1);
 93             } else {
 94                 for(int j = m[c[i][0]]; j<=m[c[i][1]]; j++) {
 95                     add(j, i+5, 1);
 96                 }
 97             }
 98         }
 99         for(int i = 1; i<=n; i++) {
100             add(i+5, i+5+n, 1);
101             add(i+5+n, t, inf);
102         }
103         cin>>str;
104         int ans = dinic();
105         if(ans == n) {
106             cout<<"T-shirts rock!"<<endl;
107         } else {
108             cout<<"I'd rather not wear a shirt anyway..."<<endl;
109         }
110     }
111 }
原文地址:https://www.cnblogs.com/yohaha/p/5018687.html