zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Vim配置及使用技巧
    终端提示符的配置
    Archlinux下i3wm与urxvt的配置
    Linux压缩命令
    Archlinux无线联网教程
    Archlinux安装和使用技巧
    Linux下硬盘分区
    Linux挂载
    Android中pullToRefresh使用
    SVN服务器搭建和使用教程
  • 原文地址:https://www.cnblogs.com/wangyiming/p/6357709.html
Copyright © 2011-2022 走看看