Poj 3436 ACM Computer Factory (最大流)

题目链接:

  Poj 3436 ACM Computer Factory

题目描述:

  n个工厂,每个工厂能把电脑s态转化为d态,每个电脑有p个部件,问整个工厂系统在每个小时内最多能加工多少台电脑?

解题思路:

  因为需要输出流水线要经过的工厂路径,如果要用电脑状态当做节点的话,就GG了。所以建图的时候要把工厂当做节点。对于节点i,能生产si电脑的节点可以进入节点i,能转化ei电脑的节点可以由i节点进入。要注意对于每一个节点要进行拆点,防止流量发生错误。

 

  1 #include <queue>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <algorithm>
  6 using namespace std;
  7 
  8 const int maxn = 55;
  9 const int INF = 0x3f3f3f3f;
 10 struct node
 11 {
 12     int x, s[20], e[20];
 13 } mach[maxn];
 14 struct node1
 15 {
 16     int s, e, x;
 17 } path[maxn*maxn];
 18 int maps[maxn*2][maxn*2], Maps[maxn*2][maxn*2];
 19 int Layer[maxn*2], p, n, num;
 20 
 21 void buildmaps (int s, int e)
 22 {
 23     for (int i=s; i<=e; i++)
 24     {
 25         int j, k;
 26         for (int j=s; j<=e; j++)
 27         {
 28             if (i == j)
 29                 continue;
 30             for (k=0; k<p; k++)
 31             {
 32                 if (mach[i].e[k]==2 || mach[j].s[k]==2)
 33                     continue;
 34                 if (mach[i].e[k] != mach[j].s[k])
 35                     break;
 36             }
 37             if (k == p)
 38                 {
 39                     if (i > 1)
 40                         Maps[i+n][j] = mach[i].x;
 41                     else
 42                         Maps[i][j] = mach[i].x;
 43                 }
 44         }
 45     }
 46     
 47     for (int i=0; i<=num; i++)
 48         for (int j=0; j<=num; j++)
 49         maps[i][j] = Maps[i][j];
 50 }
 51 
 52 bool CountLayer (int s, int e)
 53 {
 54     queue <int> Q;
 55     memset (Layer, 0, sizeof(Layer));
 56     Layer[s] = 1;
 57     Q.push (s);
 58     
 59     while (!Q.empty ())
 60     {
 61         
 62         int u = Q.front();
 63         Q.pop();
 64         
 65         for (int i=0; i<=num; i++)
 66             if (!Layer[i] && maps[u][i])
 67             {
 68                 Layer[i] = Layer[u] + 1;
 69                 Q.push (i);
 70                 if (i == e)
 71                     return true;
 72             }
 73     }
 74     return false;
 75 }
 76 
 77 int Dfs (int u, int e, int maxflow)
 78 {
 79     if (u == e)
 80         return maxflow;
 81         
 82     int uflow = 0;
 83     for (int i=0; i<=num; i++)
 84     {
 85         if (maps[u][i] && Layer[i]==Layer[u]+1)
 86         {
 87             int flow = min(maps[u][i], maxflow - uflow);
 88             flow = Dfs (i, e, flow);
 89 
 90             uflow += flow;
 91             maps[u][i] -= flow;
 92             maps[i][u] += flow;
 93             if (uflow == maxflow)
 94                 break;
 95         }
 96     }
 97         
 98     if (uflow == 0)
 99         Layer[u] = 0;
100     
101     return uflow;
102 }
103 
104 int Dinic (int s, int e)
105 {
106     int maxflow = 0;
107     
108     while (CountLayer(s, e))
109         maxflow += Dfs(s, e, INF);
110         
111     return maxflow;
112 }
113 
114 int main ()
115 {
116     while (scanf ("%d %d", &p, &n) != EOF)
117     {
118         memset (mach, 0, sizeof(mach));
119         memset (Maps, 0, sizeof(Maps));
120         mach[0].x = INF;
121         for (int i=0; i<p; i++)
122         {
123             mach[0].s[i] = INF;
124             mach[1].e[i] = INF;
125             mach[1].s[i] = 1;
126         }
127         
128         for (int i=2; i<n+2; i++)
129         {
130             scanf ("%d", &mach[i].x);
131             for (int j=0; j<p; j++)
132                 scanf ("%d", &mach[i].s[j]);
133             for (int j=0; j<p; j++)
134                 scanf ("%d", &mach[i].e[j]);
135             Maps[i][i+n] = mach[i].x;//拆点
136         }
137         
138         int ans, res;
139         res = 0;
140         num = n + n + 1;
141         
142         buildmaps (0, n+1);
143         ans = Dinic (0, 1);
144         
145         for (int i=2; i<num; i++)
146         {
147             for (int j=2; j<num; j++)
148             {
149                 
150                 if (i == j+n || j==i+n)
151                     continue;
152                     
153                 if (Maps[i][j] - maps[i][j] > 0)
154                 {
155                     path[res].x = Maps[i][j] - maps[i][j];
156                     path[res].s = (i - 2) % n + 1;
157                     path[res++].e = (j - 2) % n + 1;
158                 }
159                 
160             }
161         }
162         
163         printf ("%d %d\n", ans, res);
164         for (int i=0; i<res; i++)
165             printf ("%d %d %d\n", path[i].s, path[i].e, path[i].x);
166             
167     }
168     return 0;
169 }

 

posted @ 2015-09-01 19:00  罗茜  阅读(213)  评论(2编辑  收藏  举报