poj3436 Computer Factory

题意:

电脑公司生产电脑有N个机器,每个机器单位时间产量为Qi。 电脑由P个部件组成,每个机器工作时只能把有某些部件的半成品电脑(或什么都没有的空电脑)变成有另一些部件的半成品电脑或完整电脑(也可能移除某些部件)。求电脑公司的单位时间最大产量,以及哪些机器有协作关系,即一台机器把它的产品交给哪些机器加工。

Sample input

3 4

15 0 0 0 0 1 0

10 0 0 0 0 1 1

30 0 1 2 1 1 1
3   0 2 1 1 1 1

Sample output

25 2

1 3 15

2 3 10

输入:电脑由3个部件组成,共有4台机器,1号机器产量15, 能给空电脑加上2号部件,2号 机器能给空电脑加上2号部件和3号部件, 3号机器能把有1个2号部件和3号部件有无均可的电脑变成成品(每种部件各有一个)
输出:单位时间最大产量25,有两台机器有协作关系,
1号机器单位时间内要将15个电脑给3号机器加工
2号机器单位时间内要将10个电脑给3号机器加工

思路:

网络流模型:

1) 添加一个原点S,S提供最初的原料 00000...
2) 添加一个汇点T, T接受最终的产品 11111...
3) 将每个机器拆成两个点: 编号为i的接收节点,和编号为i+n的产出节点(n是机器数目),前者用于接收原料,后者用于提供加工后的半成品或成品。这两个点之间要连一条边,容量为单位时间产量Qi
4) S 连边到所有接收 "0000..." 或 "若干个0及若干个2" 的机器,容量为无穷大
5) 产出节点连边到能接受其产品的接收节点,容量无穷大
6) 能产出成品的节点,连边到T,容量无穷大。
7) 求S到T的最大流

实现:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <queue>
  5 using namespace std;
  6
  7 const int INF = 0x3f3f3f3f;
  8
  9 int g[105][15], p, n, q[55];
 10 int G[105][105], G_copy[105][105], layer[105], vis[105];
 11
 12 struct node
 13 {
 14     int x, y, c;
 15 };
 16
 17 bool countLayer(int s, int e)
 18 {
 19     layer[s] = 0;
 20     queue<int> q;
 21     q.push(s);
 22     memset(vis, 0, sizeof(vis));
 23     vis[s] = true;
 24     while (!q.empty())
 25     {
 26         int tmp = q.front();
 27         q.pop();
 28         for (int i = 1; i <= e; i++)
 29         {
 30             if (G[tmp][i] && !vis[i])
 31             {
 32                 layer[i] = layer[tmp] + 1;
 33                 if (i == e)
 34                 {
 35                     return true;
 36                 }
 37                 vis[i] = true;
 38                 q.push(i);
 39             }
 40         }
 41     }
 42     return false;
 43 }
 44
 45 int dinic(int s, int e)
 46 {
 47     int flow = 0;
 48     deque<int> q;
 49     while (countLayer(s, e))
 50     {
 51         memset(vis, 0, sizeof(vis));
 52         vis[s] = true;
 53         q.push_back(s);
 54         while (!q.empty())
 55         {
 56             int tmp = q.back();
 57             if (tmp == e)
 58             {
 59                 int minn = INF;
 60                 int min_index = 0;
 61                 for (int i = 1; i < q.size(); i++)
 62                 {
 63                     if (G[q[i - 1]][q[i]] && G[q[i - 1]][q[i]] < minn)
 64                     {
 65                         minn = G[q[i - 1]][q[i]];
 66                         min_index = i - 1;
 67                     }
 68                 }
 69                 for (int i = 1; i < q.size(); i++)
 70                 {
 71                     G[q[i - 1]][q[i]] -= minn;
 72                     G[q[i]][q[i - 1]] += minn;
 73                 }
 74                 while (q.size() && q.back() != min_index)
 75                 {
 76                     vis[q.back()] = false;
 77                     q.pop_back();
 78                 }
 79                 flow += minn;
 80             }
 81             else
 82             {
 83                 bool flag = false;
 84                 for (int i = 1; i <= e; i++)
 85                 {
 86                     if (G[tmp][i] && !vis[i] && layer[i] == layer[tmp] + 1)
 87                     {
 88                         vis[i] = true;
 89                         q.push_back(i);
 90                         flag = true;
 91                         break;
 92                     }
 93                 }
 94                 if (!flag && q.size())
 95                 {
 96                     q.pop_back();
 97                 }
 98             }
 99         }
100     }
101     return flow;
102 }
103
104 int main()
105 {
106     while (cin >> p >> n)
107     {
108         for (int i = 0; i < n; i++)
109         {
110             cin >> q[i];
111             for (int j = 0; j < p; j++)
112             {
113                 cin >> g[i][j];
114             }
115             for (int j = 0; j < p; j++)
116             {
117                 cin >> g[i + n][j];
118             }
119         }
120         memset(G, 0, sizeof(G));
121         for (int i = 2; i < n + 2; i++)
122         {
123             G[i][i + n] = q[i - 2];
124         }
125         for (int i = 2; i < n + 2; i++)
126         {
127             bool flag = true;
128             for (int j = 0; j < p; j++)
129             {
130                 if (g[i - 2][j] != 0 && g[i - 2][j] != 2)
131                 {
132                     flag = false;
133                     break;
134                 }
135             }
136             if (flag)
137             {
138                 G[1][i] = INF;
139             }
140         }
141         for (int i = n + 2; i < 2 * n + 2; i++)
142         {
143             bool flag = true;
144             for (int j = 0; j < p; j++)
145             {
146                 if (g[i - 2][j] != 1)
147                 {
148                     flag = false;
149                     break;
150                 }
151             }
152             if (flag)
153             {
154                 G[i][2 * n + 2] = INF;
155             }
156         }
157         for (int i = n + 2; i < 2 * n + 2; i++)
158         {
159             for (int j = 2; j < n + 2; j++)
160             {
161                 bool flag = true;
162                 for (int k = 0; k < p; k++)
163                 {
164                     if (!(g[i - 2][k] == g[j - 2][k] || g[j - 2][k] == 2))
165                     {
166                         flag = false;
167                         break;
168                     }
169                 }
170                 if (flag)
171                 {
172                     G[i][j] = INF;
173                 }
174             }
175         }
176         for (int i = 1; i <= 2 * n + 2; i++)
177         {
178             for (int j = 1; j <= 2 * n + 2; j++)
179             {
180                 G_copy[i][j] = G[i][j];
181             }
182         }
183         cout << dinic(1, 2 * n + 2) << " ";
184         int cnt = 0;
185         vector<node> v;
186         for (int i = n + 2; i < 2 * n + 2; i++)
187         {
188             for (int j = 2; j < n + 2; j++)
189             {
190                 if (i - n != j && G[i][j] != G_copy[i][j])
191                 {
192                     cnt++;
193                     node tmp;
194                     tmp.x = i - n - 1;
195                     tmp.y = j - 1;
196                     tmp.c = G_copy[i][j] - G[i][j];
197                     v.push_back(tmp);
198                 }
199             }
200         }
201         cout << cnt << endl;
202         for (int i = 0; i < v.size(); i++)
203         {
204             cout << v[i].x << " " << v[i].y << " " << v[i].c << endl;
205         }
206     }
207     return 0;
208 }
时间: 2025-01-01 07:27:04

poj3436 Computer Factory的相关文章

poj3436 ACM Computer Factory, 最大流,输出路径

POJ 3436 ACM Computer Factory 电脑公司生产电脑有N个机器,每个机器单位时间产量为Qi. 电脑由P个部件组成,每个机器工作时只能把有某些部件的半成品电脑(或什么都没有的空电脑)变成有另一些部件的半成品电脑或完整电脑(也可能移除某些部件).求电脑公司的单位时间最大产量,以及哪些机器有协作关系,即一台机器把它的产品交给哪些机器加工. Sample input 3 4 15  0 0 0  0 1 0 10  0 0 0  0 1 1 30  0 1 2  1 1 1 3

POJ-3436 ACM Computer Factory (最大流[Ford-Fulkerson])

ACM Computer Factory http://poj.org/problem?id=3436 Time Limit: 1000MS   Memory Limit: 65536K         Special Judge Description As you know, all the computers used for ACM contests must be identical, so the participants compete on equal terms. That i

POJ3436 ACM Computer Factory 【最大流】

ACM Computer Factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5412   Accepted: 1863   Special Judge Description As you know, all the computers used for ACM contests must be identical, so the participants compete on equal terms. Th

POJ-3436 ACM Computer Factory(网络流EK)

As you know, all the computers used for ACM contests must be identical, so the participants compete on equal terms. That is why all these computers are historically produced at the same factory. Every ACM computer consists of P parts. When all these

POJ3436:ACM Computer Factory(最大流)

ACM Computer Factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9963   Accepted: 3738   Special Judge 题目链接:http://poj.org/problem?id=3436 Description: As you know, all the computers used for ACM contests must be identical, so the pa

poj3436--ACM Computer Factory(最大流,拆点dinic)

ACM Computer Factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5501   Accepted: 1887   Special Judge Description As you know, all the computers used for ACM contests must be identical, so the participants compete on equal terms. Th

POJ 3436 ACM Computer Factory(网络最大流)

http://poj.org/problem?id=3436 ACM Computer Factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5286   Accepted: 1813   Special Judge Description As you know, all the computers used for ACM contests must be identical, so the particip

Poj 3436 ACM Computer Factory (最大流)

题目链接: Poj 3436 ACM Computer Factory 题目描述: n个工厂,每个工厂能把电脑s态转化为d态,每个电脑有p个部件,问整个工厂系统在每个小时内最多能加工多少台电脑? 解题思路: 因为需要输出流水线要经过的工厂路径,如果要用电脑状态当做节点的话,就GG了.所以建图的时候要把工厂当做节点.对于节点i,能生产si电脑的节点可以进入节点i,能转化ei电脑的节点可以由i节点进入.要注意对于每一个节点要进行拆点,防止流量发生错误. 1 #include <queue> 2 #

poj3436-ACM Computer Factory

ACM Computer Factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5079   Accepted: 1740   Special Judge Description As you know, all the computers used for ACM contests must be identical, so the participants compete on equal terms. Th