http://poj.org/problem?id=3436

题意好难懂,有n个工厂加工电脑半成品,半成品电脑需要p个部件。

输入p(需要的部件数) n(工厂数)

Qi  (工厂最大生产量)  Si,1 Si,2...Si,P  (s表示在工厂i声场必须满足的条件1必须已经有了,0可以没有,2可以有,也可以没有) Di,1 Di,2...Di,P,(经过i厂生产之后,所满足的条件1有,0木有)

题目建图不好了理解,建完图后就是套最大流模板的问题了。。。

首先构建网络图,一台电脑在进入生产线之前各部分的零件状态肯定全为0,离开生产线时,各部分的零件状态肯定全为1.
所以源点与输入状态全为0的机器相连,输出状态全为1机器与汇点相连,并且设定容量为INF,然后对每台机器的输入,输出
拆为两个点,容量为Q;最后判断两台机器之间,某台机器的输出状态是否可以为另一台机器的输入状态,是,则相连,容量为
INF,至此网络流图建立完毕,下面就是求最大流问题了.
但是为了输出相连的机器信息,我们在构建网络流图完毕后,应该备份一下残留矩阵residual为cresidual,当EK()完以后,
通过比较cresidual与residual的值才可以确定那两个机器之间被利用了.
View Code

#include <cstdio>#include <cstring>#include <queue>#include <iostream>#define maxn 200#define inf 0x7fffffffusing namespace std;

int g[maxn][maxn],flow[maxn],tmp[maxn][maxn];int pre[maxn];struct node{int in[20],out[20];int num;}tp[maxn];int s,e,p,n,ans;void input(){    memset(g,0,sizeof(g));for (int i = 1; i <= n; ++i)    {        cin>>tp[i].num;        g[i][i+n] = tp[i].num;for (int j = 0; j < p; ++j)        cin>>tp[i].in[j];for (int j = 0; j < p; ++j)        cin>>tp[i].out[j];    }}bool isok(node a,node b){for (int i = 0; i < p; ++i)    {if (a.out[i] + b.in[i] == 1)return false;    }return true;}int getf(int *l){int t0 = 0;int t1 = 0;for (int i = 0; i < p; ++i)    {if (l[i] == 1) t1++;else t0++;    }if (t1 == p) return 1;if (t0 == p) return 0;return -1;}void build(){    s = 0;    e = 2*n + 1;int i,j;for (i = 1; i <= n; ++i)    {for (j = 1; j <= n; ++j)        {if (i != j && isok(tp[i],tp[j]))            {                g[i + n][j] = inf;            }        }    }for (i = 1; i <= n; ++i)    {int flag1 = getf(tp[i].in);int flag2 = getf(tp[i].out);if (flag1 == 0) g[s][i] = inf;if (flag2 == 1) g[i + n][e] = inf;    }    memcpy(tmp,g,sizeof(g));}int bfs(){int i;    memset(pre,-1,sizeof(pre));for (i = s; i <= e; ++i)    flow[i] = inf;    queue<int>q;    q.push(s);while (!q.empty())    {int pos = q.front(); q.pop();if (pos == e) return flow[e];for (i = s; i <= e; ++i)        {if (i == s || g[pos][i] == 0 || pre[i] != -1) continue;            pre[i] = pos;            flow[i] = min(flow[pos],g[pos][i]);            q.push(i);        }    }return -1;}void EK(){    ans = 0;while (1)    {int d = bfs();if (d == -1) break;        ans += d;for (int i = e; i != s; i = pre[i])        {            g[pre[i]][i] -= d;            g[i][pre[i]] += d;        }    }}void print(){int ct = 0;int i,j;for (i = n + 1; i < e; ++i)    {for (j = 1; j <= n; ++j)        {if (i != j && g[i][j] < tmp[i][j])            ct++;        }    }    printf("%d %d\n",ans,ct);for (i = n + 1; i < e; ++i)    {for (j = 1; j <= n; ++j)        {if (i != j && g[i][j] < tmp[i][j])             printf("%d %d %d\n",i - n,j,tmp[i][j] - g[i][j]);        }    }}int main(){//freopen("d.txt","r",stdin);    while (~scanf("%d%d",&p,&n))    {        input();        build();        EK();        print();    }return 0;}

转载于:https://www.cnblogs.com/E-star/archive/2012/03/20/2408422.html

pku 3436 ACM Computer Factory ——最大流 EK相关推荐

  1. POJ - 3436 ACM Computer Factory(最大流+输出残余网络)

    题目链接:点击查看 题目大意:给出n个机器以及m个零件,m个零件分别代表电脑上的零件,每一个机器可以将电脑上零件的一种状态转变为另一种状态,并且每个机器都有单独的效率,现在对于每一个单独的零件,规定状 ...

  2. POJ 3436 -- ACM Computer Factory(最大流,建图)

    题目链接 Description As you know, all the computers used for ACM contests must be identical, so the part ...

  3. POJ 3436 ACM Computer Factory(最大流+路径输出)

    http://poj.org/problem?id=3436 题意: 每台计算机包含P个部件,当所有这些部件都准备齐全后,计算机就组装完成了.计算机的生产过程通过N台不同的机器来完成,每台机器用它的性 ...

  4. POJ3426 ACM Computer Factory——最大流(EK+输出路径)

    点这里 题意: 题目大意就是问把000加工到111(多少个零视输入的P而定)的最大零件个数,并且输出路径.   但是具体的加工规则真的是把我看晕了 然后我们来说说具体的加工规则:N台机器,每台机器能同 ...

  5. POJ 3436 ACM Computer Factory

    传送门:https://vjudge.net/problem/POJ-3436 题目大意: 每台电脑由p个零件组成,编号1-n.生产电脑完全由N台全自动的机器完成.每台机器能够添加一些零件和移除一些电 ...

  6. ACM Computer Factory

    ACM Computer Factory 题目链接:http://poj.org/problem?id=3436 网络流Dinic 将一个机器拆分成两个点,这两个点之间的容量为机器的加工量:建立一个超 ...

  7. A - ACM Computer Factory - poj 3436(最大流)

    题意:有一个ACM工厂会生产一些电脑,在这个工厂里面有一些生产线,分别生产不同的零件,不过他们生产的电脑可能是一体机,所以只能一些零件加工后别的生产线才可以继续加工,比如产品A在生产线1号加工后继续前 ...

  8. poj3436——ACM Computer Factory

    题目大意: 输入: 输出: 分析: 代码:转载自

  9. 最大流EK和Dinic算法

    最大流EK和Dinic算法 EK算法 最朴素的求最大流的算法. 做法:不停的寻找增广路,直到找不到为止 代码如下: @Frosero #include <cstdio> #include ...

最新文章

  1. pythondocx模板_python操作docx文档(转)
  2. 使用 Eclipse 调试 Java 程序的 10 个技巧
  3. python查看opencv版本命令行_查看python下OpenCV版本的方法
  4. 第19讲:Pyppeteer 爬取实战
  5. 沟通模型包含5个状态
  6. 还在做互联网创业梦?醒醒!
  7. 微信小程序会改变大世界吗?
  8. (life)新的一年新的一页
  9. 重载操作符解析(原)
  10. 【李宏毅2020 ML/DL】P17 Convolutional Neural Network
  11. Java网络编程从入门到精通(15):为什么要使用SocketAddress来管理网络地址
  12. 汇编语言通过WMI获取BIOS、主板、硬盘、CPU、网卡的信息
  13. 2004世界五百强企业
  14. Hadoop 3.x安装部署详细手顺
  15. python中等好用什么表示_Python十大装B语法!你会几种?
  16. python读取定位_如何使用python定位和读取Data Matrix代码
  17. 极客时间_week03_work
  18. 搭建本地 Protractor 运行环境
  19. 【Launcher开发】Android桌面布局分析
  20. 1. Java是编译型语言还是解释型语言?

热门文章

  1. InfoPath表单实战
  2. 数据结构源码笔记(C语言):线性表的单链表示
  3. 您如何查看MySQL用户权限
  4. vw 前端_一行css代码轻松实现前端响应式布局(vw+rem)
  5. PyQt5 技术篇-设置QComboBox下拉框默认值,获取下拉框当前选择的内容
  6. [YTU]_2640( 编程题:运算符重载---矩阵求和)
  7. 1.9 matlab字符与字符串
  8. Roman to Integer
  9. Matlab C混合编程
  10. 稀疏编码(Sparse Coding)(二)