POJ3436

题目链接:http://poj.org/problem?id=3436

题目大意:

  一台电脑可以分成P个部分,在生产过程中,半成品电脑有的部分已经完成(记为1),而有的部分还没有完成(记为0)。电脑生产商用N台机器生产电脑,对于放入各台机器的电脑,各自有其要求,即有些部分必须已经完成(记为1),有些部分必须还未完成(记为0),有些部分是否完成无关紧要(记为2),求怎么安排生产线使工厂的总生产效率最高。

解题思路:

  最大流问题。

  首先是建图。如果某台机器对于放入其中的电脑的要求全为0或者2,那么这台机器就是一个源点,如果某台机器生产出的电脑所有部分都为1,那么这台机器就可以看成一个汇点。这样就有多个源点和多个汇点,那么我们可以设置一个超级源点和超级汇点,超级源点指向每一个源点,每一个汇点指向超级汇点,流量限制为inf。对于每一台机器,为了表示其效率上限,我们将其拆成两个点,表示入口和出口,中间用一条流量限制为机器生存效率的线连接。而对于不同的机器,如果一台机器生产出来的电脑能够送往另一台电脑,那么就将这台机器的出口指向另一台机器的入口,流量限制为inf。建图完成,其他的交给模板。

  另一个难点是要printf出最大流经过的路径。那么我们就可以来研究模板跑完以后留下的残量网络。首先有三种路是我们为了方便解决问题而加入的,printf路径的时候必须无视掉:从超级源点流出的路,流入超级汇点的路,由机器入口流到出口的路。那么对于剩下的路,如果路上流量大于0,(或者说残量小于流量限制),那么这条路就是我们这个最大流网络中会经过的,打印出起点、终点和流量即可。

AC代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <vector>
  4 #include <cstring>
  5 #include <queue>
  6 using namespace std;
  7 const int inf = 0x7ffffff, maxn = 100 + 5;
  8 struct node {
  9     int s[12], t[12];
 10     int v;
 11 }machine[55];
 12 //模板作者:刘汝佳
 13 //**************************************************
 14 struct ans {
 15     int from, to, num;
 16 }ret[maxn];
 17 struct Edge {
 18     int from, to, cap, flow;
 19     Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f) {}
 20 };
 21 vector<int>ans[maxn];
 22 int len = 0, dis[maxn][maxn];
 23 struct Dinic {
 24     int n, m, s, t;
 25     vector<Edge> edges;
 26     vector<int> G[maxn];
 27     bool vis[maxn];
 28     int d[maxn];
 29     int cur[maxn];
 30
 31     void init(int n) {
 32         this->n = n;
 33         for (int i = 0; i < n; i++)    G[i].clear();
 34         edges.clear();
 35     }
 36     void addedge(int from, int to, int cap) {
 37         edges.push_back(Edge(from, to, cap, 0));
 38         edges.push_back(Edge(to, from, 0, 0));
 39         m = edges.size();
 40         G[from].push_back(m - 2);
 41         G[to].push_back(m - 1);
 42     }
 43     bool BFS() {
 44         memset(vis, 0, sizeof(vis));
 45         queue<int> Q;
 46         Q.push(s);
 47         d[s] = 0;
 48         vis[s] = 1;
 49         while (!Q.empty()) {
 50             int x = Q.front();    Q.pop();
 51             for (int i = 0; i < G[x].size(); i++) {
 52                 Edge &e = edges[G[x][i]];
 53                 if (!vis[e.to] && e.cap>e.flow) {
 54                     vis[e.to] = 1;
 55                     d[e.to] = d[x] + 1;
 56                     Q.push(e.to);
 57                 }
 58             }
 59         }
 60         return vis[t];
 61     }
 62     int DFS(int x, int a) {
 63         if (x == t || a == 0)    return a;
 64         int flow = 0, f;
 65         for (int &i = cur[x]; i < G[x].size(); i++) {
 66             Edge &e = edges[G[x][i]];
 67             if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow)))>0) {
 68                 e.flow += f;
 69                 edges[G[x][i] ^ 1].flow -= f;
 70                 flow += f;
 71                 a -= f;
 72                 if (a == 0)    break;
 73             }
 74         }
 75         return flow;
 76     }
 77     int Maxflow(int s, int t) {
 78         this->s = s;    this->t = t;
 79         int flow = 0;
 80         while (BFS()) {
 81             memset(cur, 0, sizeof(cur));
 82             flow += DFS(s, inf);
 83         }
 84         return flow;
 85     }
 86 };
 87 //****************************************************
 88 int main() {
 89     //    freopen("in.txt","r",stdin);
 90     int P, N;
 91     Dinic temp;
 92     scanf("%d%d", &P, &N);
 93     temp.init(2 * N + 2);
 94     for (int i = 1; i <= N; i++) {
 95         scanf("%d", &machine[i].v);
 96         for (int j = 0; j<P; j++)    scanf("%d", &machine[i].s[j]);
 97         for (int j = 0; j<P; j++)    scanf("%d", &machine[i].t[j]);
 98         bool sour = true;
 99         for (int j = 0; j<P; j++) {
100             if (machine[i].s[j] == 1) {
101                 sour = false;
102                 break;
103             }
104         }
105         if (sour)    temp.addedge(0, i, inf);
106         bool ending = true;
107         for (int j = 0; j<P; j++) {
108             if (machine[i].t[j] != 1) {
109                 ending = false;
110                 break;
111             }
112         }
113         if (ending)  temp.addedge(i + N, 2 * N + 1, inf);
114         temp.addedge(i, i + N, machine[i].v);
115     }
116     for (int i = 1; i <= N; i++) {
117         for (int j = i + 1; j <= N; j++) {
118             bool yes1 = true, yes2 = true;
119             for (int k = 0; k<P; k++) {
120                 if (machine[i].t[k]) {
121                     if (machine[j].s[k] == 0)  yes1 = false;
122                 }
123                 else {
124                     if (machine[j].s[k] == 1)  yes1 = false;
125                 }
126                 if (machine[j].t[k]) {
127                     if (machine[i].s[k] == 0)  yes2 = false;
128                 }
129                 else {
130                     if (machine[i].s[k] == 1)  yes2 = false;
131                 }
132                 if (!yes1&&!yes2)    break;
133             }
134             if (yes1)
135                 temp.addedge(i + N, j, inf);
136             if (yes2)
137                 temp.addedge(j + N, i, inf);
138         }
139     }
140     printf("%d ", temp.Maxflow(0, 2 * N + 1));
141     int cnt = 0;
142
143     for (int i = 0; i<temp.edges.size(); i++) {
144         Edge t = temp.edges[i];
145         int fw = t.flow, f = t.from, tt = t.to;
146         if (fw <= 0 || t.cap == 0 || t.cap != inf || tt>N || f<1)  continue;
147         ret[cnt].from = f - N, ret[cnt].to = tt, ret[cnt].num = fw;
148         cnt++;
149     }
150     printf("%d\n", cnt);
151     for (int i = 0; i<cnt; i++) {
152         printf("%d %d %d\n", ret[i].from, ret[i].to, ret[i].num);
153     }
154     return 0;
155 }
时间: 2024-11-09 01:53:51

POJ3436的相关文章

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

网络流-最大流:两枚[poj1459&amp;poj3436]

说说建图吧- poj1459: 增加超级源点,超级汇点,跑一遍即可. #include <cstdio> #include <cstring> #include <vector> #include <cstdlib> #include <cmath> #include <queue> #include <algorithm> using namespace std; const int MAX = 107; const i

ACMComputerFactory(POJ-3436)【最大流】

题目链接:https://vjudge.net/problem/POJ-3436 题意:要用N台机器来组装电脑,每台电脑由P个零部件构成,每一台机器的输入电脑和输出电脑的每部分都有各自的属性,机器本身也有最大产能,现在求这N台机器能够达到的最大组装速率. 思路:可以转化成最大流问题来做. 首先我们在每台机器之间建立可行的边,再对机器本身的输入和输出端口之间建边,再设一个超级源点S和一个超级汇点T,建立S与每台机器之间和每台机器与T之间的可行边,此时,最大产能即为S->T的最大流. 原文地址:ht

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 13   0 2 1 1 1 1 Sample output 25 2

ACM/ICPC 之 ACM计算机工厂-EK算法(POJ3436)

题意有点难读懂 //网络流-EK算法-ACM计算机工厂-构图重点 //Time:0Ms Memory:208K #include <iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> using namespace std; #define MAXN 55 #define INF 0x3f3f3f3f int p,n; int s,t;

poj3436网络流之最大流拆点

这题看了半天看不懂题意...还是看的网上题意写的 加一个源点一个汇点,把每个点拆成两个,这两个点的流量是v,其他联通的边都设为无穷大 输入没有1的点就与源点连接,输出只有1的点就与汇点连接 还有这个输出技巧,因为每条反向弧初始容量设置为0,因此完成增广之后,反向弧的容量即为路径. #include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include

POJ3436(KB11-A 最大流)

ACM Computer Factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8133   Accepted: 2943   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 (最大流[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