poj-3436.ACM Computer Factory(最大流 + 多源多汇 + 结点容量 + 路径打印 + 流量统计)
ACM Computer Factory
Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 10940 | Accepted: 4098 | Special Judge |
Description
As you know, all the computers used for ACM contests must be identical, so the participants compete on equal terms. That is why all these computers are historically produced at the same factory.
Every ACM computer consists of P parts. When all these parts are present, the computer is ready and can be shipped to one of the numerous ACM contests.
Computer manufacturing is fully automated by using N various machines. Each machine removes some parts from a half-finished computer and adds some new parts (removing of parts is sometimes necessary as the parts cannot be added to a computer in arbitrary order). Each machine is described by its performance (measured in computers per hour), input and output specification.
Input specification describes which parts must be present in a half-finished computer for the machine to be able to operate on it. The specification is a set of P numbers 0, 1 or 2 (one number for each part), where 0 means that corresponding part must not be present, 1 — the part is required, 2 — presence of the part doesn't matter.
Output specification describes the result of the operation, and is a set of P numbers 0 or 1, where 0 means that the part is absent, 1 — the part is present.
The machines are connected by very fast production lines so that delivery time is negligibly small compared to production time.
After many years of operation the overall performance of the ACM Computer Factory became insufficient for satisfying the growing contest needs. That is why ACM directorate decided to upgrade the factory.
As different machines were installed in different time periods, they were often not optimally connected to the existing factory machines. It was noted that the easiest way to upgrade the factory is to rearrange production lines. ACM directorate decided to entrust you with solving this problem.
Input
Input file contains integers P N, then N descriptions of the machines. The description of ith machine is represented as by 2 P + 1 integers Qi Si,1 Si,2...Si,P Di,1 Di,2...Di,P, where Qi specifies performance, Si,j — input specification for part j, Di,k — output specification for part k.
Constraints
1 ≤ P ≤ 10, 1 ≤ N ≤ 50, 1 ≤ Qi ≤ 10000
Output
Output the maximum possible overall performance, then M — number of connections that must be made, then M descriptions of the connections. Each connection between machines A and B must be described by three positive numbers A B W, where W is the number of computers delivered from A to B per hour.
If several solutions exist, output any of them.
Sample Input
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
Sample input 2
3 5
5 0 0 0 0 1 0
100 0 1 0 1 0 1
3 0 1 0 1 1 0
1 1 0 1 1 1 0
300 1 1 2 1 1 1
Sample input 3
2 2
100 0 0 1 0
200 0 1 1 1
Sample Output
Sample output 1
25 2
1 3 15
2 3 10
Sample output 2
4 5
1 3 3
3 5 3
1 2 1
2 4 1
4 5 1
Sample output 3
0 0
Hint
Source
一发AC。。。都在题解里了。
/*
本题还是比较入门级别的水题吧,思路很好想,选出所有的源点和所有的汇点,还有所有的可行边(如果一台电脑能够接受上一台电脑输出之后的结果,就说明可以从他们之间建立一条边),
接着按照多源多汇和结点容量最大流建边,跑一波最大流就ok啦,还有就是记录路径和结点容量值,嘤嘤嘤。
如果需要打印路径和统计流量,就将图备份一次,并且在存图的时候存入边的起点就ok了,跑完最大流检查一遍哪些边被用过了就ok。
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std; const int maxn = + , maxm = * + , maxp = + , inf = 0x3f3f3f3f;
int p, n, ps[maxn << ][], pe[maxn << ][], q[maxn << ], s1[maxn << ], e1[maxn << ];
int sizes, sizet, tot, tot1, cnt, head[maxn << ], que[maxn << ], dep[maxn << ], cur[maxn << ], sta[maxn << ];
struct Edge {
int to, next, cap, flow, from;
} edge[maxm << ], edges[maxm << ];
struct node {
int u, v, w;
} ans[maxm << ]; void init() {
memset(head, -, sizeof head);
tot = tot1 = ;
sizes = sizet = cnt = ;
} void addedge(int u, int v, int w, int rw = ) {
edge[tot].to = v; edge[tot].cap = w; edge[tot].flow = ; edge[tot].from = u;
edge[tot].next = head[u]; head[u] = tot ++;
edge[tot].to = u; edge[tot].cap = rw; edge[tot].flow = ; edge[tot].from = v;
edge[tot].next = head[v]; head[v] = tot ++; edges[tot1].to = v; edges[tot1].cap = w; edges[tot1].flow = ; edges[tot1].from = u;
edges[tot1].next = head[u]; head[u] = tot1 ++;
edges[tot1].to = u; edges[tot1].cap = rw; edges[tot1].flow = ; edges[tot1].from = v;
edges[tot1].next = head[v]; head[v] = tot1 ++;
} bool bfs(int s, int t, int n) {
int front = , tail = ;
memset(dep, -, sizeof dep[] * (n + ));
dep[s] = ;
que[tail ++] = s;
while(front < tail) {
int u = que[front ++];
for(int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if(edge[i].cap > edge[i].flow && dep[v] == -) {
dep[v] = dep[u] + ;
if(v == t) return true;
que[tail ++] = v;
}
}
}
return false;
} int dinic(int s,int t, int n) {
int maxflow = ;
while(bfs(s, t, n)) {
for(int i = ; i < n; i ++) cur[i] = head[i];
int u = s, tail = ;
while(cur[s] != -) {
if(u == t) {
int tp = inf;
for(int i = tail - ; i >= ; i --)
tp = min(tp, edge[sta[i]].cap - edge[sta[i]].flow);
maxflow += tp;
for(int i = tail - ; i >= ; i --) {
edge[sta[i]].flow += tp;
edge[sta[i] ^ ].flow -= tp;
if(edge[sta[i]].cap - edge[sta[i]].flow == ) tail = i;
}
u = edge[sta[tail] ^ ].to;
}
else if(cur[u] != - && edge[cur[u]].cap > edge[cur[u]].flow && dep[u] + == dep[edge[cur[u]].to]) {
sta[tail ++] = cur[u];
u = edge[cur[u]].to;
}
else {
while(u != s && cur[u] == -)
u = edge[sta[-- tail] ^ ].to;
cur[u] = edge[cur[u]].next;
}
}
}
return maxflow;
} int main() {
while(~scanf("%d %d", &p, &n)) {
init();
int s = * n + , t = s + ;
for(int i = ; i <= n; i ++) {
scanf("%d", &q[i]);//读入某一台机器的工作效率
for(int j = ; j <= p; j ++) scanf("%d", &ps[i][j]);//读入初始状态
for(int j = ; j <= p; j ++) scanf("%d", &pe[i][j]);//读入输出状态
}
bool flag = true;
for(int i = ; i <= n; i ++) {
for(int j = ; j <= n; j ++) {
if(i ^ j) {//如果i != j
flag = true;
for(int k = ; k <= p; k ++) {//判断机器j是否可以接受机器i加工之后的状态
if(pe[i][k] + ps[j][k] == ) {
flag = false;
break;
}
}
if(flag) addedge(i + n, j, inf);
}
}
flag = true;
for(int k = ; k <= p; k ++) {//判断机器i是否为源点
if(ps[i][k] % == ) {
flag = false;
break;
}
}
if(flag) s1[sizes ++] = i;
flag = true;
for(int k = ; k <= p; k ++) {//判断机器i是否为汇点
if(pe[i][k] == ) {
flag = false;
break;
}
}
if(flag) e1[sizet ++] = i;
}
for(int i = ; i < sizes; i ++) addedge(s, s1[i], inf);
for(int i = ; i < sizet; i ++) addedge(n + e1[i], t, inf);
for(int i = ; i <= n; i ++) addedge(i, n + i, q[i]);
int maxflow = dinic(s, t, * n + );
for(int i = ; i <= tot; i += ) {
if(edge[i].flow > && edge[i].from != s && edge[i].to != t && abs(edge[i].from - edge[i].to) != n) {
ans[++ cnt].u = edge[i].from > n ? edge[i].from - n: edge[i].from;
ans[cnt].v = edge[i].to > n ? edge[i].to - n : edge[i].to;
ans[cnt].w = edges[i].cap - edge[i].cap;
// ans[++ cnt] = (node){edge[i].from, edge[i].to, edge[i].flow};
ans[cnt].w = edge[i].flow;
}
}
if(maxflow == ) cnt = ;
printf("%d %d\n", maxflow, cnt);
for(int i = ; i <= cnt; i ++) {
printf("%d %d %d\n", ans[i].u, ans[i].v, ans[i].w);
}
}
return ;
}
poj-3436.ACM Computer Factory(最大流 + 多源多汇 + 结点容量 + 路径打印 + 流量统计)的更多相关文章
- Poj 3436 ACM Computer Factory (最大流)
题目链接: Poj 3436 ACM Computer Factory 题目描述: n个工厂,每个工厂能把电脑s态转化为d态,每个电脑有p个部件,问整个工厂系统在每个小时内最多能加工多少台电脑? 解题 ...
- POJ 3436 ACM Computer Factory 最大流,拆点 难度:1
题目 http://poj.org/problem?id=3436 题意 有一条生产线,生产的产品共有p个(p<=10)零件,生产线上共有n台(n<=50)机器,每台机器可以每小时加工Qi ...
- poj 3436 ACM Computer Factory 最大流+记录路径
题目 题意: 每一个机器有一个物品最大工作数量,还有一个对什么物品进行加工,加工后的物品是什么样.给你无限多个初始都是000....的机器,你需要找出来经过这些机器操作后最多有多少成功的机器(111. ...
- POJ 3436 ACM Computer Factory (网络流,最大流)
POJ 3436 ACM Computer Factory (网络流,最大流) Description As you know, all the computers used for ACM cont ...
- POJ - 3436 ACM Computer Factory 网络流
POJ-3436:http://poj.org/problem?id=3436 题意 组配计算机,每个机器的能力为x,只能处理一定条件的计算机,能输出特定的计算机配置.进去的要求有1,进来的计算机这个 ...
- POJ - 3436 ACM Computer Factory(最大流)
https://vjudge.net/problem/POJ-3436 题目描述: 正如你所知道的,ACM 竞赛中所有竞赛队伍使用的计算机必须是相同的,以保证参赛者在公平的环境下竞争.这就是所有这些 ...
- POJ 3436 ACM Computer Factory(最大流+路径输出)
http://poj.org/problem?id=3436 题意: 每台计算机包含P个部件,当所有这些部件都准备齐全后,计算机就组装完成了.计算机的生产过程通过N台不同的机器来完成,每台机器用它的性 ...
- POJ 3436 ACM Computer Factory (拆点+输出解)
[题意]每台计算机由P个零件组成,工厂里有n台机器,每台机器针对P个零件有不同的输入输出规格,现在给出每台机器每小时的产量,问如何建立流水线(连接各机器)使得每小时生产的计算机最多. 网络流的建图真的 ...
- POJ 3436 ACM Computer Factory
题意: 为了追求ACM比赛的公平性,所有用作ACM比赛的电脑性能是一样的,而ACM董事会专门有一条生产线来生产这样的电脑,随着比赛规模的越来越大,生产线的生产能力不能满足需要,所以说ACM董事会想 ...
随机推荐
- flask基础之一
flask基础之一 hello world #从flask这个包中导入Flask这个类 #Flask这个类是项目的核心,以后的很多操作都是基于这个类的对象 #注册url,注册蓝图都是这个类的对象 fr ...
- 非父子组件通过事件传值-vue
1.创建中央事件总线:额外的 new Vue()2.$emit 触发事件3.$on 监听事件 在使用组件的文件中: <template> <div> <x-test :b ...
- 前端之JavaScript:JS之DOM对象一
js之DOM对象一 一.什么是HTML DOM HTML Document Object Model(文档对象模型) HTML DOM 定义了访问和操作HTML文档的标准方法 HTML DOM 把 ...
- Django【第21篇】:Ajax之FormData
ajax补充--------FormData等... 一.回顾上节知识点 1.什么是json字符串? 轻量级的数据交换格式 2.定时器:关于setTimeout setTimeout(foo,3000 ...
- CTF Jarvisoj Web(session.upload_progress.name php 上传进度)
Jarvisoj Web 题目地址:http://web.jarvisoj.com:32784/index.php <?php //A webshell is wait for you ini_ ...
- ESP8266-12F
读者可以把ESP8266当做Arduino+WiFi功能来开发 ESP8266模块支持STA/AP/STA+AP 三种工作模式: STA 模式:ESP8266模块通过路由器连接互联网,手机或电脑通过互 ...
- MySQL数据库3分组与单表、多表查询
目录 一.表操作的补充 1.1null 和 not null 1.2使用not null的时候 二.单表的操作(import) 2.1分组 2.1.1聚合函数 2.1.2group by 2.1.3h ...
- node.js从入门到起飞
第一个node程序: 首先创建一个js文件,命名index.js(可随意),然后在文件里面输入 : console.log("Hello World"); 使用 Git Bash ...
- SPOJ 694 || 705 Distinct Substrings ( 后缀数组 && 不同子串的个数 )
题意 : 对于给出的串,输出其不同长度的子串的种类数 分析 : 有一个事实就是每一个子串必定是某一个后缀的前缀,换句话说就是每一个后缀的的每一个前缀都代表着一个子串,那么如何在这么多子串or后缀的前缀 ...
- 约数定理(two)
筛约数个数和 理论基础: 1.对n质因数分解,n=p1^k1 * p2^k2 * p3^k3 …… 则n的约数个数为(k1+1)*(k2+1)*(k3+1)…… 2.线性筛素数时,用i和素数pj来筛掉 ...