poj3436 ACM Computer Factory

题意:

  n个工厂加工电脑,电脑有p个部件。每个工厂加工的电脑必须是满足它对原材料的需求。p个部件,0代表不能有,1必须有,2代表可有可无。然后经过加工后,这个工厂输出的电脑各个部件的情况,0代表没有,1代表有。每个工厂有一个生产效率。求单位时间内的最多能生产的完整电脑数量。

解决:

  每个工厂拆成两个点,流量为该工厂效率。超级源连接对p个部件需求都为0的工厂,超级汇连接输出p个部件都为1的工厂 。求一次最大流。

 

 

  1 #include <cstdio>

  2 #include <cstring>

  3 #include <queue>

  4 #include <climits>

  5 

  6 const int MAXN = 100 + 20;

  7 const int INF = INT_MAX;

  8 

  9 int g[MAXN];

 10 

 11 int n, p;

 12 

 13 struct Mach{

 14     int q, in[11], out[11];

 15 }mach[MAXN<<2];

 16 

 17 struct Edge{

 18     int v, f, pre;

 19 }e[MAXN*MAXN], e_bak[MAXN*MAXN];

 20 int e_n;

 21 

 22 struct Flow{

 23     int u, v, f;

 24 }flow[MAXN<<2];

 25 int f_e;

 26 

 27 int layer[MAXN];

 28 

 29 int dfs(int u, int sink, int flow)

 30 {

 31     if(u == sink)

 32         return flow;

 33     int now_flow = 0;

 34     for(int i = g[u]; i && flow; i = e[i].pre){

 35         int v = e[i].v;

 36         int f = e[i].f;

 37         if(f > 0 && layer[v] == layer[u] + 1){

 38             int d = dfs(v, sink, std::min(f, flow));

 39             e[i].f -= d;

 40             e[i^1].f += d;

 41             flow -= d;

 42             now_flow += d;

 43         }

 44     }

 45     return now_flow;

 46 }

 47 

 48 void bfs(int src, int sink)

 49 {

 50     memset(layer, -1, sizeof layer);

 51     std::queue<int> que;

 52     que.push(src);

 53     layer[src] = 0;

 54     while(que.empty() == false){

 55         int u = que.front();

 56         que.pop();

 57         for(int i = g[u]; i; i = e[i].pre){

 58             int v = e[i].v;

 59             int f = e[i].f;

 60             if(f > 0 && layer[v] == -1){

 61                 que.push(v);

 62                 layer[v] = layer[u] + 1;

 63             }

 64         }

 65     }

 66 }

 67 

 68 int dinic(int src, int sink)

 69 {

 70     int res = 0;

 71     while(true){

 72         bfs(src, sink);

 73         if(layer[sink] == -1){

 74             return res;

 75         }

 76         res += dfs(src, sink, INF);

 77     }

 78 }

 79 

 80 

 81 

 82 void addEdge(int u, int v, int f)

 83 {

 84     ++ e_n;

 85     e[e_n].v = v;

 86     e[e_n].f = f;

 87     e[e_n].pre = g[u];

 88     g[u] = e_n;

 89     

 90     ++e_n;

 91     e[e_n].v = u;

 92     e[e_n].f = 0;

 93     e[e_n].pre = g[v];

 94     g[v] = e_n;

 95 }

 96 

 97 void init()

 98 {

 99     e_n = 1;

100     f_e = 0;

101     memset(g, 0, sizeof g);

102     memset(e, 0, sizeof e);

103     memset(e_bak, 0, sizeof e_bak);

104     memset(flow, 0, sizeof flow);

105     memset(mach, 0, sizeof mach);

106 }

107 

108 int main()

109 {

110     while(~scanf("%d%d", &p, &n)){

111         init();

112         //scanf("%d%d", &p, &n);

113         int src = 0;

114         int sink = n*2+1;

115         // input

116         for(int i = 1; i <= n; ++ i){

117             scanf("%d", &mach[i].q);

118             for(int j = 1; j <= p; ++ j){

119                 scanf("%d", &mach[i].in[j]);

120             }

121             for(int j = 1; j <= p; ++ j){

122                 scanf("%d", &mach[i].out[j]);

123             }    

124             addEdge(i, i+n, mach[i].q);

125         }

126         // addEdge

127         for(int i = 1; i <= n; ++ i){

128             bool ok = true;

129             for(int j = 1; j <= p; ++ j){

130                 if(mach[i].in[j] == 1){

131                     ok = false;

132                     break;

133                 }

134             }

135             if(ok == true){

136                 addEdge(src, i, INF);

137             }

138     

139             ok = true;

140             for(int j = 1; j <= p; ++ j){

141                 if(mach[i].out[j] != 1){

142                     ok = false;

143                     break;

144                 }

145             }

146             if(ok == true){

147                 addEdge(i+n, sink, INF);

148             }

149     

150             for(int j = 1; j <= n; ++ j){

151                 if(i == j){

152                     continue;

153                 }

154                 ok = true;

155                 for(int k = 1; k <= p; ++ k){

156                     if(mach[i].in[k] == 1 && mach[j].out[k] == 0){

157                         ok = false;

158                         break;

159                     }

160                     if(mach[i].in[k] == 0 && mach[j].out[k] == 1){

161                 

162                         ok = false;

163                         break;

164                     }

165                 }

166                 if(ok == true){

167                     addEdge(j+n, i, INF);

168                 }

169             }

170         }

171     

172         for(int i = 2; i <= e_n; ++ i){

173             e_bak[i] = e[i];

174         }

175 

176         printf("%d ", dinic(src, sink));

177 

178         for(int u = n+1; u <= n*2; ++ u){

179             for(int i = g[u]; i; i = e[i].pre){

180                 int v = e[i].v;

181                 if(v == 0 || v > n)

182                     continue;

183                 int f = e[i].f;

184                 int f_bak = e_bak[i].f;

185                 if(f_bak > f){

186                     f_e ++;

187                     flow[f_e].u = u-n;

188                     flow[f_e].v = v;

189                     flow[f_e].f = f_bak - f;

190                 }

191             }

192         }

193         printf("%d\n", f_e);

194         for(int i = 1; i <= f_e; ++ i){

195             printf("%d %d %d\n", flow[i].u, flow[i].v, flow[i].f);

196         }

197     }

198 }

 

你可能感兴趣的:(factory)