题目链接:https://vjudge.net/problem/POJ-3436

Sample input 1
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

题目:P  —— 一台电脑由p个零件组成

   N —— 工厂有n台加工组装电脑的机器

  Q —— i-th机器每单位时间能工作的数量
 
当每个未成品需要放入某个机器进一步加工的时候,它需要满足这台机器能正常工作的前提,
即它必须满足某些零件已经组装好了。
样例1: 前p个数字表示,进入i-th台机器,必须满足这些条件(0表示这个零件不能被安装 1表示这个零件必须被安装 2表示这个零件有无被安装无影响)
后p个数字表示,某个未成品被i-th台机器加工完成后,满足了这些条件(0表示这个零件没被安装 1表示这个零件被安装了)
问:怎么安排机器工作方案,能使得工作效率最大化,安排情况有很多,输出一种即可。 思路:比较清楚,一个超级源点,一个超级汇点,一台机器需要拆成入点和出点,一台机器的入点和出点流量为该机器单位时间的工作量,其他点与点之间的流量就是INF了。
重点就是哪些边能建立起来比较麻烦,图建好了,跑一个Dinic就OK了。
 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std; const int N = ,INF = (int)1e9;
int p,n,tot;
int G[N][N],head[N],lev[N];
queue<int > que;
struct info{
int in[],out[];
int cap;
}info[N];//存机器的信息
struct node{
int to,nxt,flow;
}e[N*N]; void init_main(){
for(int i = ; i <= n; ++i)
for(int j = ; j <= n; ++j) G[i][j] = ; for(int i = ; i <= *n+; ++i) head[i] = -; tot = ;
} void init_bfs(){
for(int i = ; i <= *n+; ++i) lev[i] = ;
while(!que.empty()) que.pop();
} inline void add(int u,int v,int flow){
e[tot].to = v;
e[tot].flow = flow;
e[tot].nxt = head[u];
head[u] = tot++;
} //是否可连边
inline bool check(int x,int y){
for(int i = ; i <= p; ++i){
if(info[y].in[i] == ) continue;
if(info[x].out[i] != info[y].in[i]) return false;
}
return true;
} //建边
void rebuild(){
for(int i = ; i <= n; ++i){
if(check(,i)){
add(,i,INF); add(i,,);
}
if(check(i,*n+)){
add(i+n,*n+,INF); add(*n+,i+n,);
}
}
for(int i = ; i <= n; ++i){
for(int j = ; j <= n; ++j){
if(i == j){
add(i,i+n,info[i].cap); add(i+n,i,);
}
else if(check(i,j)){
add(i+n,j,INF); add(j,i+n,);
}
}
}
} int dfs(int now,int flow,int t){
if(now == t) return flow;
int to,sum = ,tmp = ;
for(int o = head[now]; ~o; o = e[o].nxt){
to = e[o].to;
if((lev[to] == lev[now] +) && e[o].flow && (tmp = dfs(to,min(flow - sum, e[o].flow),t))){
//需要的路径流量 G数组来存机器之间的联系
if(now > n && now < *n+ && to != *n+){
G[now-n][to] += tmp;
}
e[o].flow -= tmp;
e[o^].flow += tmp;
if((sum += tmp) == flow) return sum;
}
}
return sum;
} bool bfs(int s,int t){
init_bfs();
que.push();
while(!que.empty()){
int now = que.front(); que.pop();
for(int o = head[now]; ~o; o = e[o].nxt){
int to = e[o].to;
if(!lev[to] && e[o].flow){
lev[to] = lev[now] + ;
que.push(to);
}
}
}
if(lev[t]) return true;
else return false;
} int mf(int s,int t){
int max_flow = ;
while(bfs(s,t)){
max_flow += dfs(s,INF,t);
//cout << "max_flow " << max_flow << endl;
}
return max_flow;
} int main(){ while(~scanf("%d%d",&p,&n)){
init_main();
//读入信息 0超级源点 2*n+1超级汇点
for(int i = ; i <= n; ++i){
scanf("%d",&info[i].cap);
for(int j = ; j <= p; ++j) scanf("%d",&info[i].in[j]);
for(int j = ; j <= p; ++j) scanf("%d",&info[i].out[j]);
}
info[].cap = INF; info[*n+].cap = INF;
for(int i = ; i <= p; ++i){
info[].out[i] = ;
info[*n+].in[i] = ;
}
//建图
rebuild();
//Dinic
int _mf = mf(,*n+),line = ;
//统计需要的联系数量
for(int i = ; i <= n; ++i){
for(int j = ; j <= n; ++j){
if(G[i][j]) ++line;
}
}
printf("%d %d\n",_mf,line);
//输出联系
for(int i = ; i <= n; ++i){
for(int j = ; j <= n; ++j){
if(G[i][j]) printf("%d %d %d\n",i,j,G[i][j]);
}
}
} return ;
}
 

kuangbin专题专题十一 网络流 POJ 3436 ACM Computer Factory的更多相关文章

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

    POJ 3436 ACM Computer Factory (网络流,最大流) Description As you know, all the computers used for ACM cont ...

  2. Poj 3436 ACM Computer Factory (最大流)

    题目链接: Poj 3436 ACM Computer Factory 题目描述: n个工厂,每个工厂能把电脑s态转化为d态,每个电脑有p个部件,问整个工厂系统在每个小时内最多能加工多少台电脑? 解题 ...

  3. POJ - 3436 ACM Computer Factory 网络流

    POJ-3436:http://poj.org/problem?id=3436 题意 组配计算机,每个机器的能力为x,只能处理一定条件的计算机,能输出特定的计算机配置.进去的要求有1,进来的计算机这个 ...

  4. POJ 3436 ACM Computer Factory 最大流,拆点 难度:1

    题目 http://poj.org/problem?id=3436 题意 有一条生产线,生产的产品共有p个(p<=10)零件,生产线上共有n台(n<=50)机器,每台机器可以每小时加工Qi ...

  5. POJ - 3436 ACM Computer Factory(最大流)

    https://vjudge.net/problem/POJ-3436 题目描述:  正如你所知道的,ACM 竞赛中所有竞赛队伍使用的计算机必须是相同的,以保证参赛者在公平的环境下竞争.这就是所有这些 ...

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

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

  7. POJ 3436 ACM Computer Factory (拆点+输出解)

    [题意]每台计算机由P个零件组成,工厂里有n台机器,每台机器针对P个零件有不同的输入输出规格,现在给出每台机器每小时的产量,问如何建立流水线(连接各机器)使得每小时生产的计算机最多. 网络流的建图真的 ...

  8. POJ 3436 ACM Computer Factory

    题意:   为了追求ACM比赛的公平性,所有用作ACM比赛的电脑性能是一样的,而ACM董事会专门有一条生产线来生产这样的电脑,随着比赛规模的越来越大,生产线的生产能力不能满足需要,所以说ACM董事会想 ...

  9. poj 3436 ACM Computer Factory 最大流+记录路径

    题目 题意: 每一个机器有一个物品最大工作数量,还有一个对什么物品进行加工,加工后的物品是什么样.给你无限多个初始都是000....的机器,你需要找出来经过这些机器操作后最多有多少成功的机器(111. ...

随机推荐

  1. ZR提高失恋测2(9.7)

    ZR提高失恋测2(9.7) 网址http://www.zhengruioi.com/contest/392 版权原因,不放题面 A 首先,我们发现对于匹配串\(s\)中所有满足\(s_i \not = ...

  2. wpf遮罩~~~(搬运过来的)

    方便自己以后用,原文:https://blog.csdn.net/lwwl12/article/details/78472235 直接上代码 public partial class BaseWind ...

  3. UTF-8、UTF-16、UTF-32编码的相互转换(不使用现成的函数)

    最近在考虑写一个可以跨平台的通用字符串类,首先需要搞定的就是编码转换问题. vs默认保存代码文件,使用的是本地code(中文即GBK,日文即Shift-JIS),也可以使用带BOM的UTF-8.gcc ...

  4. Docker Desktop: Error response from daemon: driver failed programming external connectivity on endpoint xxx 问题

    右击任务栏 Docker 图标 `Restart` 或 `Quit Docker Deskto` 后之前正常的 zookeeper 容器不会自动启动 通过命令 docker start zk1 启动报 ...

  5. git之github解决冲突

    1.先创建一个txt文件,并进行编辑 2.然后推送到github,过程看之前的教程. 3.在另一个文件夹拉取(用小乌龟拉取),分别在克隆文件夹和原本文件夹操作test.txt. 4.把本体推送给服务器 ...

  6. The third day of Crawler learning

    连续爬取多页数据 分析每一页url的关联找出联系 例如虎扑 第一页:https://voice.hupu.com/nba/1 第二页:https://voice.hupu.com/nba/2 第三页: ...

  7. 力扣208——实现 Trie (前缀树)

    这道题主要是构造前缀树节点的数据结构,帮助解答问题. 原题 实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作. 示例: Trie trie = ...

  8. 鼠标右键新建Markdown文档

    首先放一张github某项目中.md文件中的内容图片 Windows系统下,使用 Typora 软件来进入Markdown文档的编写非常容易,而且入门门槛非常的低 存在的问题: 习惯了使用Markdo ...

  9. 【记】VM VirtualBox 网络地址转换(NAT)使用详解

    1. 查看虚拟机Centos6的ip 但是这个IP地址并不能直接连接,因为本地VBox网络连接方式采用的是“网络地址转换(NAT)”(如上上图所示),也就是说 10.0.2.15 这地址是转换的. 2 ...

  10. MQ使用:apollo和rabbitmq

    apollo apollo 是一个更快.更可靠.更容易维护的消息代理,它是由最初的ActiveMQ的基础构建的.它使用一个完全不同的线程和消息调度架构来实现这一点.与ActiveMQ一样,apollo ...