题目链接: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. Redis内存回收机制

    为什么需要内存回收? 原因有如下两点: 在 Redis 中,Set 指令可以指定 Key 的过期时间,当过期时间到达以后,Key 就失效了. Redis 是基于内存操作的,所有的数据都是保存在内存中, ...

  2. CodeForces - 721D Maxim and Array (贪心)

    Recently Maxim has found an array of n integers, needed by no one. He immediately come up with idea ...

  3. vue中的computed和watch区别

    在vue.js官方文档中看到computed和watch获取全名的一个例子: var var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', ...

  4. 【转载】VS Code 中的代码自动补全和自动导入包

    原文连接:https://maiyang.me/post/2018-09-14-tips-vscode/ VSCode 必须安装以下插件: 首先你必须安装 Golang 插件,然后再给 Go 安装工具 ...

  5. 0016 CSS 背景:background

    目标 理解 背景的作用 css背景图片和插入图片的区别 应用 通过css背景属性,给页面元素添加背景样式 能设置不同的背景图片位置 [插入图片,不用设置img元素的父元素.自身元素大小,即可见,但是背 ...

  6. easyUI dataGrid主从表点击展开问题

    昨天在公司写代码遇到了一个问题,就是在用easyUI做主从表的时候在查询之后点击展开的时候不能再次展开了.先说一下主从表我也是第一次用 效果如下图: 然后点击前面的小加号出现以下效果: 然而遇到了一个 ...

  7. 安装Docker Machine

    什么是Docker Machine Docker Machine是Docker官方编排项目之一,由Go语言实现,负责在多种平台上快速安装Docker环境,Github项目主页 它支持Linux.Mac ...

  8. PS/2的相关知识

    PS/2接口 很多微机上采用PS/2口来连接鼠标和键盘.PS/2接口与传统的键盘接口除了在接口外型.引脚有不同外,在数据传送格式上是相同的.现在很多主板用PS/2接口插座连接键盘,传统接口的键盘可以通 ...

  9. lucene&tantivy对比

    写入对比每个路径下都只能有一个IndexWriter负责写入,通过writer.lock实现.不同:lucene可以多个线程共享一个IndexWriter,每个线程负责写一个segment,从addD ...

  10. BeanUtils 如何拷贝 List?

    BeanUtils 如何拷贝 List? 一.背景 我们在DO.Model.VO层数据间可能经常转换数据: Entity对应的是持久层数据结构(一般是数据库表的映射模型); Model 对应的是业务层 ...